我正在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
调用Person
。apply
可以调用具有特定this
对象值(我们新创建的Person
实例)和参数的函数作为数组——这正是我们所需要的。
因此,上面将使用name
和gender
参数初始化我们的空对象,完成通常使用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)
用于调用构造函数来启动刚刚创建的实例