Object构造函数作为较大对象中的函数

时间:2016-06-16 15:42:43

标签: javascript oop object constructor

由于重复的关键搜索术语,这一点非常棘手。我有这个电路游戏我正在制作。仅供参考,就风格而言,我使用全部大写名称作为对象,虽然它们可能会稍微改变(例如,number_of_boards或其他东西),但不能重复用于其他内容,但属性名称可以重复使用(例如,如果我在一页上有我的凯尔特结生成器和电路游戏,我会KNOT.drawCIRCUIT_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都附加了所有这些函数。

所以问题是如何将多个对象构造函数作为非实例绑定函数,这些函数是另一个对象的所有属性?我甚至不知道这个简明的问题是否措辞得当。

1 个答案:

答案 0 :(得分:2)

这是模块使用的确切模式。例如:

export function FooCtor() {
  this.stuff = 3;
}

将成为:

exports.FooCtor = FooCtor;
function FooCtor() {
  this.stuff = 3;
}

在对象中包含构造函数(它们只是函数)不会导致任何问题。

您遇到的混淆as Pointy mentionednew运算符在函数调用中对this所做的事情。如果您正在针对可以合理地充当构造函数的函数调用new,则运行时将把一个新的上下文放在一起,其中大部分为空的对象分配给this并使用该函数调用该函数。它与完成不完全不同:

newInstance = FooCtor.call({}, ...args)

完成规范以找出发生的原因

从规范的§12.3.3开始(new运营商),它说:

  

MemberExpression MemberExpression 参数

     
      
  1. 返回EvaluateNew( MemberExpression,Arguments )。
  2.   

EvaluateNew将我们带到§12.3.3.1.1,其中第3-4步说:

  

ref 成为评估 constructProduction 的结果。   让构造函数为GetValue( ref )。

它将通过任何属性访问器链(foo.barfoo[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并不关心,只要它获得一个作为构造函数有意义的函数。如果你给它一个合理的功能,这个链只是设置一个新的对象并处理所有的原型链接。