《JavaScript那些事》--JavaScript手写new方法

手写new方法

在JavaScript中,经常使用new一个构造函数去创建一个对象。
然而我们再了解new标识符的作用后,也能实现一个自己的new。

了解new方法做了哪些事

new一个 构造函数/类 时,new做了一下操作:

  1. 创建一个对象
  2. 运行构造函数
  3. 将构造函数的this指向指向 新创建的对象
  4. 返回这个对象

代码实现

准备一个构造函数

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 狗子

一些思考

  1. 为什么Object.create()中使用fn.prototype而不是fn本身?
    因为 Object.create(arg1, args2)方法中,arg1是创建的新对象的对象原型,args2是赋给新对象的可枚举属性(即赋给新对象本身,而不是新对象原型链上的属性,且可枚举、可配置等属性默认值都为false)。
    使用fn.prototype,即创建的新对象的原型与fn的原型对象相一致。
posted @ 2022-02-10 11:00  小虾米在code江湖  阅读(178)  评论(0编辑  收藏  举报