2015-04-22 37 views
1

我在一個文件已經此解析器類類的NodeJS:與變量

module.exports = function Parser() {  

    this.myVar = ""; 

    var parse = function (inputString) { 
     this.myVar = "somethingAfterParse"; 
    } 

    return { 
     initWithString: function(inputString) { 
      parse(inputString) 
     }, 
     name: this.myVar 
    }; 

}; 

然後說,在「主」文件JS,我以這種方式使用的解析器:

var Parser = require("./Parser.js"); 
var parserInstance = new Parser(); 
parserInstance.initWithString("somestring"); 
console.log("Parser var:", parserInstance.myVar); 

沒有錯誤,但日誌打印一個空的名字..爲什麼?

+0

你鴕鳥政策需要實例只使用Parser.initWithString()。在你的解析函數解析後返回this.name ... – solick

回答

3

這裏是我會做:

function Parser() { 
    this.myVar = ""; 
} 
Parser.prototype.initWithString = function (inputString) { 
    this.myVar = "somethingAfterParse"; 
}; 

module.exports = Parser; 

你的方法,註釋

module.exports = function Parser() { 
    // public property "myVar" of any new Parser object 
    this.myVar = ""; 

    // anonymous function assigned to private variable "parse" 
    var parse = function (inputString) { 
     // "this" will likely be the global object here, dangling error 
     this.myVar = "somethingAfterParse"; 
    } 

    // return API object - unnecessary and makes debugging harder (*) 
    return { 
     // anonymous function that calls private "parse" function 
     initWithString: function(inputString) { 
      // calling parse without defining "this", definitely an error (**) 
      parse(inputString) 
     }, 
     // the above is equivalent to and therefore better written as 
     // initWithString: parse, 

     // copy of (!) public property myVar, definitely an error (***) 
     name: this.myVar 
    }; 
}; 

當你遺漏了冗餘位(並使用的原型鏈)你最終以我上面的建議。


*我知道這是用於定義對象的公共接口一個流行的方法。我個人不喜歡它。從JS構造函數返回一個對象有效地打破了new運營商的用處:

  • 你讓無法訪問已分配給this之前在構造函數中,像你this.myVar對象的用戶的一切。
  • 您會收到一包沒有類型信息的屬性。從技術上講,這是有效的,但在調試過程中並不好。比較:

    function A() { 
        this.a = "A"; 
        return { 
         a: "a" 
        }; 
    } 
    
    function B() { 
        this.b = "B"; 
    } 
    
    new A(); // Object {a: "a"} 
    new B(); // B {b: "B"} 
    

**this在函數內部將指功能叫上(在背景)的任何對象。

通常點符號爲您服務:object.method()thisobject裏面method

但是,您不要在任何對象上調用parse()函數。在沒有上下文的情況下調用的任何函數都會在全局對象的上下文中運行(在Window的瀏覽器中)。

您將需要通過使用var self = this;前面的initWithString正文以及parse.apply(self, arguments)正文指定上下文。

最後,「讓我們返回一個對象作爲API」的方法使事情變得比他們需要的更困難。

***原始類型總是由JavaScript中的值賦值。就像數字或布爾值一樣,您不能引用字符串。將它們分配給其他變量會複製它們。

+0

你絕對說服了我!我從來沒有考慮過你的解決方案,非常感謝 –

1

而不是返回匿名object您可以返回一個Parser類型。

module.exports = function Parser() {  
    var self = this; 
    self.name = ""; 

    self.parse = function (inputString) { 
     self.name = inputString + " parsed"; 
    } 

    return self; 
}; 

然後說,在 「主」 文件JS,我以這種方式使用的解析器:

var Parser = require("./Parser.js"); 
var parserInstance = new Parser(); 
parserInstance.parse("something"); 
console.log("Parser name:", parserInstance.name); // Parser name: something parsed 
1

你必須使用.call.apply

module.exports = function Parser() { 

    this.name = ""; 

    var parse = function(inputString) { 
     this.name = "somethingAfterParse"; 
    } 

    return { 
     initWithString: function(inputString) { 
      parse.call(this, inputString) 
     }, 
     name: this.name 
    }; 

};