new 操作符

7/30/2021 Javascript

# new 操作符做了什么

  • 创建的一个空的 js 对象,即就是{}
  • 将空对象的原型 prototype 指向构造函数的原型
  • 将空对象作为构造函数的上下文,即改变 this 的指向
  • 对构造函数有返回值的判断
  1. 如果返回值是基础数据类型,则忽略返回值,返回 new 操作符生成的对象
  2. 如果返回值是引用数据类型,则使用 return 的返回,也就是操作符无效
function Person(name) {
    this.name = name
    return 1
}
let me = new Person('april')
console.log(me) // {name: 'april'}
1
2
3
4
5
6
function Person(name) {
    this.name = name
    console.log('hahah', [].shift.call(arguments))
    return { age: 12 }
}
let me = new Person('april')
console.log(me) // {age: 24}
1
2
3
4
5
6
7

# 模拟实现

new 是关键字,无法直接覆盖,定义一个函数来模拟 new 的效果

function objectFactory() {
    let obj = new Object()
    Constructor = [].shift.call(arguments)
    obj.__proto__ = Constructor.prototype
    let result = Constructor.apply(obj, arguments)
    // typeof null 返回的也是object
    return typeof result === 'object' ? result || obj : obj
}
1
2
3
4
5
6
7
8

# 模拟方法使用

function Person(name) {
    this.name = name
}
let result = objectFactory(Person, 'april')
console.log(result) // { name: 'april'}
1
2
3
4
5

# 注意

三种创建空对象的区别 三种创建空对象的区别

所以由 Object.create 生成的对象,调用原型上的方法会报错

function objectFactory() {
    let obj = Object.create(null)
    Constructor = [].shift.call(arguments)
    obj.__proto__ = Constructor.prototype
    let result = Constructor.apply(obj, arguments)
    // typeof null 返回的也是object
    return typeof result === 'object' ? result || obj : obj
}
function Person(name) {
    this.name = name
}
Person.prototype.say = function() {
    console.log('hello')
}
let result = objectFactory(Person, 'april')
result.say() // Uncaught TypeError: result.say is not a function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
上次更新: 8/2/2021, 6:39:30 PM