试图模仿'新'运算符

时间:2018-04-06 09:48:13

标签: javascript constructor

如何使用myNew函数模拟'new'运算符?尝试了一切,但我无法让它发挥作用。

function Person(name) {
 this.name = name;
}

Person.prototype.getName = function() {
 return this.name;
}

function myNew(){
  var obj = Object.create(Object.prototype);
  var instance = this.apply(obj, arguments);
  return instance;
}


var person = myNew(Person, 'Test');
console.log(person instanceof Person);  // true
person.getName();   // Test

2 个答案:

答案 0 :(得分:1)

如果你想要一个没有Reflect.construct的模拟,试试这个:

function myNew(constructor) {
  var instance = Object.create(constructor.prototype)
  var args = Array.from(arguments)
  args.shift()
  constructor.apply(instance, args)
  return instance
}

如果您支持ES6,可以将其缩短为:

function myNew(constructor, ...args) {
  var instance = Object.create(constructor.prototype)
  constructor.apply(instance, args)
  return instance
}

编辑:刚刚注意到ES6中提供了Array.from但是如果你想支持ES5,你可以轻松地模拟它

编辑2: 查看新运算符的MDN页面,我注意到我忘记了构造函数创建对象的重要步骤。我使用的算法几乎与页面上解释的算法完全相同,除了关键部分,有构造函数实际返回(并非所有构造函数都返回undefined)。在这种情况下,返回的对象 对新表达式的评估。所以函数的最终形式(我希望)将是

function myNew(constructor, ...args) {
  var instance = Object.create(constructor.prototype)
  var obj = constructor.apply(instance, args)
  if(obj instanceof Object) return obj
  return instance
}

答案 1 :(得分:0)

您可以使用Reflect.construct

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/construct



function Person(name) {
 this.name = name;
}

Person.prototype.getName = function() {
 return this.name;
}


var person = Reflect.construct(Person, ['Test']);
console.log(person instanceof Person);  // true
console.log(person.getName());   // Test