模拟实现new

new 运算符建立一个用户定义的对象类型的实例或具备构造函数的内置对象的实例。浏览器

上面的定义有点抽象,咱们来经过一个例子看 new 运算符扮演的角色app

function Foo(name, age) {
  this.name = name;
  this.age = age;
}
Foo.prototype.getName = function() {
  return this.name;
};
Foo.prototype.foo = "foo";
var f = new Foo("zhangsan", 18);
f.getName(); // zhangsan
f.foo; // foo
复制代码

上面经过 new 建立了一个新的对象,而且这个对象经过原型链访问到了原型上的方法和属性,因此 new 运算符就是执行构造函数返回一个实例对象。函数

new 运算符在执行时执行了下面四步:测试

  1. 建立一个空的简单 JavaScript 对象(即{});
  2. 连接该对象(即设置该对象的构造函数)到另外一个对象 ;
  3. 将步骤 1 新建立的对象做为 this 的上下文 ;
  4. 若是该函数没有返回对象,则返回 this。

实现

根据上面的执行步骤咱们来尝试实现下,固然 new 操做符确定是模拟不了了,下面经过函数的形式展现ui

function newCall(fn) {
  var args = Array.prototype.slice.call(arguments, 1);
  var obj = {};
  obj.__proto__ = fn.prototype;
  var result = fn.apply(obj, args);
  return result && typeof result === "object" ? result : obj;
}
复制代码

Ok,到这里就实现了一个模拟 new 的操做,咱们测试一下this

function Otaku(name, age) {
  this.name = name;
  this.age = age;

  this.habit = "Games";
}

Otaku.prototype.strength = 60;

Otaku.prototype.sayYourName = function() {
  console.log("I am " + this.name);
};

function newCall(fn) {
  var args = Array.prototype.slice.call(arguments, 1);
  var obj = {};
  obj.__proto__ = fn.prototype;
  var result = fn.apply(obj, args);
  return result && typeof result === "object" ? result : obj;
}

var person = newCall(Otaku, "Kevin", "18");

console.log(person.name); // Kevin
console.log(person.habit); // Games
console.log(person.strength); // 60
复制代码

撒花 ✿✿ ヽ(°▽°)ノ ✿,不过额外提醒一下__proto__是浏览器实现的非标准属性,通常状况下不推荐使用,不过既然是模拟 es5 推荐的Object.setPrototypeOf确定没办法用了,只能将就着用了es5

相关文章
相关标签/搜索