js-实现new操作符

365 阅读1分钟

实现步骤:

  • 首先创建一个空对象;
  • 把新创建的对象的原型(__ proto __)指向函数的prototype, 这两步可以使用 Object.create 方法来实现
  • 执行函数, 并把函数的this指向新创建的对象
  • 判断函数执行结果
// 实现方法:
Function.prototype.myNew = function () {
  var obj = Object.create(this.prototype); // Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
  var result = this.apply(obj, arguments); // 执行函数, 并把函数的this指向新创建的obj
  return (typeof result === 'object' || typeof result === 'function') ? result : obj; // 如果函数返回的是Object或Function,则返回result, 否则返回obj
};

测试

情况1:函数没有return

function Test(name, age) {
  this.name = name;
  this.age = age;
}

Test.prototype.say = function() {
  console.log("name = " + this.name + ",age = " + this.age);
};

// 原始调用方式
var test1 = new Test("张三", 20);
console.log(test1);  // Test{name: "张三", age: 20}
test1.say();  // name = 张三,age = 20

// 新调用方式
var test2 = Test.myNew("张三", 18);
console.log(test2); // Test{name: "张三", age: 18}
test2.say(); // name = 张三,age = 18

情况2:函数返回Object

function Test(name, age) {
  this.name = name;
  this.age = age;
  return {
    msg: 'Object测试'
  };
}

Test.prototype.say = function() {
  console.log("name = " + this.name + ",age = " + this.age);
};

// 原始调用方式
var test1 = new Test("张三", 20);
console.log(test1);  // {msg: "Object测试"}
test1.say();  // error: test1.say is not a function

// 新调用方式
var test2 = Test.myNew("张三", 18);
console.log(test2); // {msg: "Object测试"}
test2.say(); // error: test1.say is not a function

情况3:函数返回Function

function Test(name, age) {
  this.name = name;
  this.age = age;
  return function () {

  }
}

Test.prototype.say = function() {
  console.log("name = " + this.name + ",age = " + this.age);
};

// 原始调用方式
var test1 = new Test("张三", 20);
console.log(test1);  // ƒ () {}
test1.say();  // error: test1.say is not a function

// 新调用方式
var test2 = Test.myNew("张三", 18);
console.log(test2); // ƒ () {}
test2.say(); // error: test1.say is not a function