JavaScript之深入浅出原型和原型链(下)

68 阅读1分钟

往期回顾:

JavaScript之深入浅出原型和原型链(上)

续:

附录:

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 }

image.png 可以看到:

  • 构造函数通过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 { age26 }  
}  
const t = new Test('xxx')  
console.log(t) // { age: 26 }  
console.log(t.name// 'undefined'

对比可以发现,当构造函数返回为原始值时,原始值不起任何作用,当返回一个对象时,只能访问或者使用到返回对象里的值。

那我们是不是今天总结一下new做了哪些工作呢?

  1. 创建一个新的对象obj
  2. 将这个新对象与构造函数通过原型链连接起来
  3. 将构造函数中的this绑定到obj
  4. 根据构造函数的返回类型判断,如果是原始值,忽略原始值,如果是对象,则返回一个对象。

如图:

fb5df5249945275a225535c6704abb42.png

手写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  
}