new具体做了什么事情?

160 阅读2分钟

通俗来说,我们都知道new一般做了下面四件事:

1、创建一个空对象;

2、将空对象的原型,指向于构造函数的原型;

3、将空对象作为构造函数的上下文(改变this指向);

4、对有返回值的构造函数做判断处理;

详细来分析这四个点:

  • 创建一个空对象

这个其实就在内存中开辟一个新的空间,创建一个新的对象。若直接打印一个new对象的话可以看到返回的是一个空对象。

- 将空对象的原型,指向于构造函数的原型

将空对象的__proto__指向Foo的原型Foo.prototype,这两个做==判断的话会返回true.

- 将空对象作为构造函数的上下文(改变this指向)

若直接执行构造函数的话,此时内部的this指向的是window,因为是全局下。

function Foo(){
    console.log(this);
     this.name = 'jm'
}
console.log(Foo())
VM441:2 Window {0: global, 1: global, 2: global, 3: global, 4: global, 5: global, 6: global, 7: global, 8: global, 9: global, 10: global, window: Window, self: Window, document: document, name: '', location: Location, …}
VM441:5 undefined
undefined
function Foo(){
    console.log('qq',this);
     this.name = 'jm'
}
console.log('cc',new Foo())
VM546:2 qq Foo {}name: "jm"[[Prototype]]: Objectconstructor: ƒ Foo()[[Prototype]]: Object
VM546:5 cc Foo {name: 'jm'}

- 对有返回值的构造函数做判读处理

如果构造函数有返回值,return的是一个基本类型,则对new,没有影响。

但是如果返回的是一个引用类型,则new 就不起作用了。

手写new

//定义构造函数
function Fun(age,name){
  this.age = age
  this.name = name
  return 1
}
function myNew(fn,...args){
  //1,先创建空对象
  //var obj = Object.create({})
  var obj = {}
  //2,obj的__proto__指向构造函数的原型
  Object.setPrototypeOf(obj,fn.prototype)
  //3,改变this指向,执行构造函数内部函数
  var result = fn.apply(obj,args)
  //4,判断return
  return result instanceof Object?result:obj
}