冬天来了,好好学习,天天向上。
在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函数验证