《JavaScript那些事》--JavaScript手写new方法
手写new方法
在JavaScript中,经常使用new一个构造函数去创建一个对象。
然而我们再了解new标识符的作用后,也能实现一个自己的new。
了解new方法做了哪些事
new一个 构造函数/类 时,new做了一下操作:
- 创建一个对象
- 运行构造函数
- 将构造函数的this指向指向 新创建的对象
- 返回这个对象
代码实现
准备一个构造函数
function Dog(name){
this.name = name;
}
Dog.prototype.say = function() {
console.log('name is', this.name);
}
实现new
function _new(fn, ...args) {
//1. 创建新对象
let obj = Object.create(fn.prototype);
//2. 运行构造函数, 3.将this指向 新对象
let res = fn.apply(obj, args);
//4. 返回这个 对象(但得先判定下对象的类型)
return res instanceof Object ? res : obj;
}
对比检验
let dog1 = new Dog('旺财');
let dog2 = _new(Dog, '狗子');
dog1.say(); //name is 旺财
dog2.say(); //name is 狗子
可以看见我们的手写的new是成功的
完整代码
function Dog(name){
this.name = name;
}
Dog.prototype.say = function() {
console.log('name is', this.name);
}
function _new(fn, ...args) {
//1. 创建新对象
let obj = Object.create(fn.prototype);
//2. 运行构造函数, 3.将this指向 新对象
let res = fn.apply(obj, args);
//4. 返回这个 对象(但得先判定下对象的类型)
return res instanceof Object ? res : obj;
}
let dog1 = new Dog('旺财');
let dog2 = _new(Dog, '狗子');
dog1.say(); //name is 旺财
dog2.say(); //name is 狗子
一些思考
- 为什么Object.create()中使用fn.prototype而不是fn本身?
因为 Object.create(arg1, args2)方法中,arg1是创建的新对象的对象原型,args2是赋给新对象的可枚举属性(即赋给新对象本身,而不是新对象原型链上的属性,且可枚举、可配置等属性默认值都为false)。
使用fn.prototype,即创建的新对象的原型与fn的原型对象相一致。
离大侠再近一步!