手撕new()到底做了些什么?
new的实现步骤
要创建 Person 的新实例,必须使用 new 操作符。以这种方式调用构造函数实际上会经历以下 4个步骤:
(1) 创建一个新对象;
var
obj = {};
[toc]
(2) 将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象) ;
obj.__proto__ = Base.prototype;
(3) 执行构造函数中的代码(为这个新对象添加属性) ;
Base.call(obj);
(4) 返回新对象(若返回的是基本数据类型则忽略并返回新对象,若返回的是引用类型则正常使用)。
步骤(4)中返回值的不同会有什么结果?
返回基本数据类型
function Car (price) {
this.price = price
return 20
}
let bigCar = new Car(90)
console.log(bigCar.price) // 90
可以看到返回基本数据类型时返回值会被忽略
返回引用数据类型
function Car (price) {
this.price = price
return { km: 200 }
}
let bigCar = new Car(90)
console.log(bigCar.price, bigCar.km) // undefined, 200
可以看到返回引用数据类型会被正常使用
实现一个new
function _new() {
let target = {}; //创建的新对象
//第一个参数是构造函数
let [constructor, ...args] = [...arguments];
//执行[[原型]]连接;target 是 constructor 的实例
target.__proto__ = constructor.prototype;
//执行构造函数,将属性或方法添加到创建的空对象上,用result接收构造函数的返回值
let result = constructor.apply(target, args);
if (result && (typeof (result) == "object" || typeof (result) == "function")) {
//如果构造函数执行的结构返回的引用类型,则返回对象或者函数
return result;
}
//如果构造函数返回的不是一个对象,返回创建的新对象
return target;
}
阅读剩余
版权声明:
作者:chun
链接:https://chun53.top/272.html
文章版权归作者所有,未经允许请勿转载。
THE END