我可以将几个原型方法绑定到对象实例吗?

时间:2014-08-16 01:22:55

标签: javascript node.js

我还在学习javascript的怪癖。

所以我有一个“类”,或创建的函数如下:

function Parser(){
    ....
}

Parser.prototype = {
    init: function(){...},
    parseChar: {}
}

然后,我将parseChar对象的一些子方法添加到原型中,如下所示:

Parser.prototype.parseChar["*"] = function(){...}
Parser.prototype.parseChar["/"] = function(){...}

那么如何在这些函数中引用 this 引用引用Parser的创建实例? 对象parseChar

我试过了:

Parser.prototype.parseChar["*"] = function(){...}.bind(??)

我猜这显然不起作用,因为此时实例甚至不存在。

我只希望 this 引用引用每个相应的实例,以便能够访问这些原型函数中的Parser属性。

我想这可能需要构造函数中的一些魔法?我不知道,我只是希望我不必从根本上改变这一点,因为我非常喜欢使用Parser.prototype.whatever语法定义函数的方式。


当前代码

function Parser(){
    var that = this;

}

Parser.prototype = {
    state: {...},
    parseChar: {},
    init: function(){},
    parse: function(fileName){
        //random stuff
    }
}

Parser.prototype.parseChar["*"] = function(){
    console.log(that);
}

然后在另一个测试文件中:

var Parser = require('./Parser.js');
var parser = new Parser();
parser.parse("Parser.js");

顺便说一句,这是 node.js;)


潜在解决方案

看起来这个解决了我的问题 不,它没有,虽然我仍然不确定它是最好的解决方案,所以我不打算接受它。

在构造函数中,我添加了:

//Bind prototype methods to the instance
for (key in this.parseChar){
    var property = this.parseChar[key];

    if(this.parseChar[key] instanceof Function){
        this.parseChar[key] = this.parseChar[key].bind(this);
    }
}

现在,在原型方法中,我可以添加如下内容:

console.log(this.state);

它有效。

我可以看到这种方法有两个问题中的一个。如果其中一个是正确的或不正确的,请告诉我!

1) 此方法有效,但实际上它会在每个对象上创建一个函数实例。在这种情况下,最小化原型随附的冗余实例化的整个吸引力已经消失。那会好的,因为我不会创建太多实例,我喜欢这个解决方案的可读性。

不是这样的。每个实例仍然调用原型的方法

2) 每次创建新实例时,它实际上都会将原型的方法绑定到该实际实例,因此如果我创建了Parser的多个实例,则在原型之后方法绑定到新实例及其所有属性,然后所有前面的实例将引用最新的实例。那会很糟糕。

几乎,除了相反。出于某种原因,每个连续的实例引用第一个,而不是最新创建的

仍在寻找解决方案......

2 个答案:

答案 0 :(得分:1)

以下可能是一个解决方案:

function ParseChar(parser){
  this.parser=parser;
}
ParseChar.prototype["*"] = function(){
    console.log(this.parser);
}


function Parser(name){
  //here is where you know the instance
  this.parseChar = new ParseChar(this);
  this.name=name;
}
Parser.prototype.init = function(){};

var p = new Parser('p');
p.parseChar['*']();
p1 = new Parser('p1');
p1.parseChar['*']();

在第二个块中,您尝试使用闭包来获取this的值。仅当that变量与使用that的函数位于同一功能块中时,它才有效。

您可以执行以下操作,但它会为每个Parser实例创建闭包和parseChar函数,因此在我看来它不如此答案中提到的第一个解决方案好。

function Parser(){
  //begin function block Parsers
  var that = this;
  this.parseChar = {
    //function using that is within the function
    //  declaring that so it is available now
    '*':function(){
      console.log(that);
    }
  }
}

有关原型和构造函数here的更多信息。

关于闭包的更多信息here

答案 1 :(得分:0)

如果您只是为了返回that而创建一个闭包,该怎么办?

Parser内:

var that = this;
self: function {return that ;} 

然后使用self()