【问题标题】:Using apply() to chain constructors in JavaScript?在 JavaScript 中使用 apply() 链接构造函数?
【发布时间】:2019-01-22 09:24:32
【问题描述】:

我在MDN学习apply(),有一个例子我想不通:

// Create constructor method for array of args
Function.prototype.construct = function(aArgs) {
  var oNew = Object.create(this.prototype);
  this.apply(oNew, aArgs);
  return oNew;
};

this.apply(oNew, aArgs) 是做什么的?

【问题讨论】:

  • apply 中的第一个参数是作用域,第二个和后续参数是传递给您正在应用的函数的参数。
  • @Baruch 实际上,应用的第一个参数是绑定,而不是范围。范围是一个完全不同的概念

标签: javascript apply


【解决方案1】:

首先:这个函数的目的是什么?

目标

这个原型函数constructor 被定义为提供new 的替代方案。在new Person(a,b) 需要这样的参数的地方,此函数提供了一种将这些参数作为数组传递的方法。

附带说明:应该说扩展语法使得这样的特性变得不必要,因为我们可以像这样传递这样的数组:new Person(...[a,b])。不过好吧……

使用示例

假设我们有一个构造函数:

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

我有一个带有参数的数组:

var args = ["Helen", "F"];

那么我们可以做:

var person = new Person(args[0], args[1]);

但我们想将args 作为单个参数传递。现在这个原型函数将帮助我们。我们现在可以这样做:

var person = Person.construct(args);

// Create constructor method for array of args
Function.prototype.construct = function(aArgs) {
  var oNew = Object.create(this.prototype);
  this.apply(oNew, aArgs);
  return oNew;
};

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

var args = ["Helen", "F"];

var person = Person.construct(args);

console.log(person);

它是如何工作的

当调用Person.construct(args) 时,this 对象将是Person,即我们的构造函数。

那么下面就完成了:

var oNew = Object.create(this.prototype);

这将创建一个Person 对象,但实际上并没有调用构造函数Person,因此该对象没有被初始化。它只是一个空对象,是Person 的一个实例。

所以我们需要用我们拥有的参数以某种方式调用Person。我们可以使用apply

this.apply(oNew, aArgs);

回想一下thisPerson,所以我们在这里通过apply 调用Personapply 可以调用具有特定 this 对象值(我们新创建的 Person 实例)和数组形式的参数的函数——这正是我们所需要的。

因此,上面将使用namegender 参数初始化我们的空对象,完成您通常使用new 进行的完整创建和初始化。

【讨论】:

  • 感谢您的宝贵时间和精彩的解释!我认为这里的关键点是自定义的construct() 将始终与Foo.construct() 等普通构造函数一起使用,因此this 将引用Foo
  • 有史以来最好的解释!!它来自@trincot 的演示代码让我们的大脑更轻松,非常感谢你
【解决方案2】:

此函数的工作方式类似于 Javascript 中的运算符 new
您可以了解newMDN 中的工作原理
例如,如果您定义如下构造函数

function Foo(name, age) {
  this.name = name
  this.age = age
}

Foo.prototype.hello = function() {
  console.log('hello' + this.name + this.age)
}

如果您已经像您展示的示例一样定义了Function.prototype.construct
然后您可以使用const a = new Foo('a', 1)const a = Foo.construct('a', 1) 创建相同的对象

this.apply(oNew, aArgs)用于调用构造函数来初始化刚刚创建的实例

【讨论】:

  • 感谢您花费时间和精力的伙伴!非常感谢。
猜你喜欢
  • 2012-10-08
  • 2023-04-08
  • 2011-03-22
  • 1970-01-01
  • 1970-01-01
  • 2013-02-07
  • 1970-01-01
  • 2011-12-01
  • 1970-01-01
相关资源
最近更新 更多