通俗来说,我们都知道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
}