往期回顾:
续:
附录:
4.3 new
先看代码,让我们看看new具体干了什么:
function foo(a) {
this.a = a;
console.log(this); // foo { a: 1 }
}
foo..prototype.getA = function(){
console.log(this.a)
}
let foo1 = new foo(1);
foo1.getA() // 1
console.log(foo1); // foo { a: 1 }
可以看到:
- 构造函数通过
new创建出来的实例可以访问到构造函数的属性 - 构造函数通过
new创建出来的实例可以访问到构造函数原型链中的属性
再看两段代码:
function Test(name) {
this.name = name
return 1
}
const t = new Test('xxx')
console.log(t.name) // 'xxx'
// 注意分开
function Test(name) {
this.name = name
console.log(this) // Test { name: 'xxx' }
return { age: 26 }
}
const t = new Test('xxx')
console.log(t) // { age: 26 }
console.log(t.name) // 'undefined'
对比可以发现,当构造函数返回为原始值时,原始值不起任何作用,当返回一个对象时,只能访问或者使用到返回对象里的值。
那我们是不是今天总结一下new做了哪些工作呢?
- 创建一个新的对象
obj - 将这个新对象与构造函数通过原型链连接起来
- 将构造函数中的
this绑定到obj上 - 根据构造函数的返回类型判断,如果是原始值,忽略原始值,如果是对象,则返回一个对象。
如图:
手写new
function myNew(Func, ...args) {
// 1.创建一个新对象
const obj = Object.create(null)
// 2.新对象原型指向构造函数原型对象
obj.__proto__ = Func.prototype
// 3.将构建函数的this指向新对象
let result = Func.apply(obj, args)
// 4.根据返回值判断
return result instanceof Object ? result : obj
}