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属性是否出现在对象的原型链中的任何位置

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理