函数实现new的功能
要实现一个类似new操作符的函数首先我们来分析一下 new关键字都干了些什么 先来看个demo
function Person(name,age) {
this.name = name,
this.age = age
}
Person.prototype.sayName = function() {
console.log(this.name);
}
let p = new Person('zhangsan',18)
console.log('p :>> ', p);
// 打印结果如下:
Person {name: "zhangsan", age: 18}
age: 18
name: "zhangsan"
__proto__:
sayName: ƒ ()
constructor: ƒ Person(name,age)
__proto__: Object
我们可以看到,当构造函数的执行结果没有返回值(返回undefined)时,new关键字干的事情可以总结为以下几点:
- 以构造函数的原型为原型创建了一个新的实例
- 把构造函数身上的属性和方法添加到新的实例身上
- 返回创建的新实例
这是构造函数没有返回值的例子,其实返回值为非Object类型时都是这样的,接下来我们再来看下当返回值为对象类型时会发生什么
function Person(name,age) {
this.name = name,
this.age = age
return {
height: 181
}
}
Person.prototype.sayName = function() {
console.log(this.name);
}
let p = new Person('zhangsan',18)
console.log('p :>> ', p);
// 打印结果如下
p :>> {height: 181}
我们可以看到当构造函数的返回结果为一个对象时,经new关键字返回的仍是这个对象
经过上面的总结,我们就做出了下面的简单实现
function _new(obj, ...args) {
// 1. 以传入的构造函数的原型为原型创建一个新的实例
const newObj = Object.create(obj.prototype)
// 2. 把构造函数的身上的属性和方法赋值给新实例
const result = obj.apply(newObj, args)
// 3. 判断执行构造函数的返回结果 如果是对象则返回该对象 否则返回新实例
return result instanceof Object ? result : newObj
}
总结
实现一个类似new操作符的函数需要做的事:
- 以构造函数的原型为原型创建一个新的实例
- 把构造函数身上的属性和方法添加到新的实例身上
- 如果构造函数的执行结果为一个对象则返回该对象,否则返回上述新创建的实例