在JavaScript中使用apply()链接构造函数



我正在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)做什么?

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

目标

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

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

示例使用

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

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);

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

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

此函数与Javascript中的运算符new类似
您可以弄清楚new在MDN中是如何工作的
例如,如果您定义了一个构造函数,如下面的

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)用于调用构造函数来启动刚刚创建的实例

最新更新