包含变量

时间:2015-04-22 10:14:04

标签: javascript node.js mocha

我在文件中使用了这个解析器类:

module.exports = function Parser() {      

    this.myVar = "";

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

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

};

然后,在" main"文件js,我用这种方式使用解析器:

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

没有错误,但日志打印一个空名称..为什么?

3 个答案:

答案 0 :(得分: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将引用在( context )上调用函数的任何对象。

通常,点符号会为您执行此操作:object.method()this设置为object内的method

但是,您不会在任何对象上调用parse()函数。任何没有上下文的函数都在全局对象的上下文中运行(在Window的浏览器中)。

您需要先使用var self = this;以及parse.apply(self, arguments)正文中的initWithString来指定上下文。

最后整个"让我们返回一个对象作为API"方法使事情变得比他们需要的更困难。

*** 原始类型始终按JavaScript在值中指定。就像数字或布尔一样,你不能引用字符串。将它们分配给其他变量会复制它们。

答案 1 :(得分: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

答案 2 :(得分: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
    };

};