由于重复的关键搜索术语,这一点非常棘手。我有这个电路游戏我正在制作。仅供参考,就风格而言,我使用全部大写名称作为对象,虽然它们可能会稍微改变(例如,number_of_boards
或其他东西),但不能重复用于其他内容,但属性名称可以重复使用(例如,如果我在一页上有我的凯尔特结生成器和电路游戏,我会KNOT.draw
和CIRCUIT_BOARD.draw
)
所以,这是我当前设置的简短版本:
CIRCUIT_BOARD = {
"blankGridSquare": function(){
//Returns brand new object that is one blank grid square of the map
}
, "blankMap": function(width,height){
//Returns brand new object that has a bunch of blank grid squares
}
, "copyMap": function(map){
//Returns new object with the same value as parameter map
}
, "newBoard": function(svg,width,height,ioPlugs,map){
//Returns new object with a target svg,
//either a blank map or a copy of the given map,
//a set of ioPlugs,
//the electric current set up,
//etc.
//Initializes a few other things
}
// and other functions of course...
}
我不想摆脱将所有功能包装在一个变量中,因为我希望能够灵活地将多个游戏放在一个页面上。我已经读过,使构造函数正确地使用this
关键字。但是每当我尝试将this
用于这些构造函数时,我会得到一个附加了大量函数的映射,其中每个gridSquare都附加了所有这些函数。
所以问题是如何将多个对象构造函数作为非实例绑定函数,这些函数是另一个对象的所有属性?我甚至不知道这个简明的问题是否措辞得当。
答案 0 :(得分:2)
这是模块使用的确切模式。例如:
export function FooCtor() {
this.stuff = 3;
}
将成为:
exports.FooCtor = FooCtor;
function FooCtor() {
this.stuff = 3;
}
在对象中包含构造函数(它们只是函数)不会导致任何问题。
您遇到的混淆as Pointy mentioned是new
运算符在函数调用中对this
所做的事情。如果您正在针对可以合理地充当构造函数的函数调用new
,则运行时将把一个新的上下文放在一起,其中大部分为空的对象分配给this
并使用该函数调用该函数。它与完成不完全不同:
newInstance = FooCtor.call({}, ...args)
完成规范以找出发生的原因:
从规范的§12.3.3开始(new
运营商),它说:
MemberExpression :新 MemberExpression 参数
- 返回EvaluateNew( MemberExpression,Arguments )。
醇>
EvaluateNew
将我们带到§12.3.3.1.1,其中第3-4步说:
让 ref 成为评估 constructProduction 的结果。 让构造函数为GetValue( ref )。
它将通过任何属性访问器链(foo.bar
,foo[bar]
,无论如何)向下运行。接下来,同一部分的第9步说:
返回构造(构造函数, argList )。
导致§7.3.13以及施工过程的内部行为。
请注意,EvaluateNew
的第9步不指定newTarget
参数Construct
,这会触发Construct
中的第1步:
如果未传递 newTarget ,请将 newTarget 设为 F 。
Construct
的第5步执行到§9.2.2定义的构造函数[[Construct]]
属性。第8步说明:
如果 kind 是" base" ,请执行OrdinaryCallBindThis( F,calleeContext,thisArgument )。
所以我们回到5.a中 thisArgument 的定义:
让 thisArgument 成为OrdinaryCreateFromConstructor( newTarget ,"%ObjectPrototype%" )。
将我们反弹到§9.1.14,实际上(最终)将创建新对象用作构造函数的上下文:
抽象操作OrdinaryCreateFromConstructor创建一个普通对象,其[[Prototype]]值是从构造函数的prototype属性中检索的(如果存在)。否则,intrinsicDefaultProto命名的内在函数用于[[Prototype]]。
此时我们距离构造函数的访问方式还有几英里远。 new
并不关心,只要它获得一个作为构造函数有意义的函数。如果你给它一个合理的功能,这个链只是设置一个新的对象并处理所有的原型链接。