乐趣区

JS实现一个new

实现一个 new
代码如下:

var Dog = function(name) {this.name = name;}
Dog.prototype.bark = function() {console.log('wang');
}
Dog.prototype.sayName = function() {console.log('my name is', this.name);
}

var xiaobai = new Dog('小白');
xiaobai.sayName();
xiaobai.bark();

// 实现 new
var _new = function() {var constructor = Array.prototype.shift.call(arguments);  //Dog
  var args = arguments;
  const obj = new Object();
  obj.__proto__ = constructor.prototype;
  constructor.call(obj, ...args);
  return obj;
}

var xiaohei = _new(Dog, '小黑');
xiaohei.bark();
xiaohei.sayName();

console.log(xiaohei instanceof Dog);    //true

解析

  1. 思路:

    • 创建一个新对象 obj
    • 把 obj 的__proto__指向 Dog.prototype 实现继承
    • 执行构造函数, 传递参数, 改变 this 指向,Dog.call(obj, …args)
    • 返回 obj
  2. 解析:

    • var constructor = Array.prototype.shift.call(arguments); //Dog
      _new() 的第一个参数是 Dog,arguments 返回的是_new 的实参, 因此 constructor 为 Dog
    • var args = arguments; 获取剩下的参数
    • const obj = new Object(); 新建对象
    • obj.__proto__ = constructor.prototype; 把新建对象的__proto__指向 Dog 的原型链上
    • constructor.call(obj, …args); 传递参数, 改变 this 指向

执行结果

  • console.log(Dog.prototype);

  • console.log(xiaobai);

  • console.log(xiaohei);

  • console.log(xiaohei instanceof Dog); true

instanceof 运算符用于测试构造函数的 prototype 属性是否出现在对象的原型链中的任何位置

退出移动版