乐趣区

老生常谈,new运算符到底干了啥

冬天来了,好好学习,天天向上。在 js 里面,得益于字面量对象,我们可以轻松的创建出一个对象,比如 var o = {name: ‘tom’}, 就可以直接创建对象 o。而在其它 oo 语言里面,无法通过这样的方式创建一个对象,一般会借助构造方法和 new 运算符。
先看个例子,
function Person (name) {
this.name = name
}

function Animal (type) {
this.type = type
return {type: ‘dog’}
}
const p1 = Person(‘tom’)
const p2 = new Person(‘tom’)

const a1 = Animal(‘cat’)
const a2 = new Animal(‘cat’)
p1,p2,a1,a2 分别等于什么?
p1 是函数 Person 执行的结果,而函数 Person 没有返回值,所以 p1 = undefined;同理 a1 = {type: ‘dog’}
p2 是 Person 的实例, p2 = {name: ‘tom’};a2 是 Animal 的实例,a2 = {type: ‘dog’}
那么问题来了,为什么不是期望中的 a2 = {type: ‘cat’}
因为 new 主要干了下面几件事:

创建一个新对象 o,并将新对象 o 的原型对象指向构造函数的原型属性
将构造函数的 this 指向新对象 o
执行构造函数中的代码,如果返回值是个对象 (引用类型) 则返回该对象,否则返回新对象 o(注意:如果返回 null 也返回新对象 o)

针对上面的 Person 类,可以依据上面的规则写出 new 函数
const mynew = (Func, name) => {
let o = {}
o.__proto__ = Func.prototype
let res = Func.call(o, name)
if(res instanceof Object) {
return res
} else {
return o
}
}

执行 mynew 函数验证

退出移动版