2

我试图了解如何最好地使用 JavaScript 模块模式。我的问题是似乎没有办法从内部引用模块,因为this它被设置为Window对象。

我有这个简单的测试代码:

var Test = function() {
    var that = this;

    return {
        something: function() {
            console.info(that);
        }
    }
}

var test1 = Test();
test1.something();

var test2 = Test();
test2.something();

两者都test1打印test2Window对象的引用而不是模块本身。

知道如何更改它以使我this在模块内部有效吗?

4

3 回答 3

3

如果你做了

var test1 = new Test()

然后你可以做

test1.something(); 

另一种模块结构是执行以下操作:

var myModule = function () {
    var obj = {};
    obj.something = function () { 
         return console.log(obj);
    };
    obj.something2 = function () {
         return console.log(obj === this); // true
    };
    return obj;
};
var test = myModule();
test.something();
test.something2();

希望这可以帮助

于 2013-01-08T10:05:41.977 回答
1

我认为您将 JavaScript 模块模式与 JavaScript 构造函数混淆了。

JavaScript 构造函数

如果您编写一个函数并new在其前面使用关键字调用它,则该函数被称为构造函数。

它将自动返回一个新对象,您可以使用this关键字在构造函数中引用该对象。

var Test = function() {
    var that = this;

    this.something = function () {
        console.info(that);
        console.info(this);
    };
}

var test1 = new Test();
test1.something();

您可以改为返回自己的对象,但通常不会在构造函数中这样做,您只需使用this

var Test = function() {
    var that = this;

    return {
        something: function () {
            console.info(that);
            console.info(this);
        }
    };
}

var test1 = new Test();
test1.something();

如果你new使用它前面的关键字调用它,那么它就像一个普通函数一样被调用,这意味着this对它内部的任何引用都指的是该函数是其属性的对象(在没有其他任何东西的情况下, 将是全局对象,在 Web 浏览器中是window)。

var geoff = {
    Test: function () {
        var that = this;

        return {
            something: function () {
                console.info(that);
            }
        };
    }
};

var test2 = geoff.Test();
var test3 = Test();

注意:对于构造函数,您通常会在其原型对象上定义方法,这样就不会为您使用构造函数创建的每个对象不必要地重新定义方法:

var Test = function() {
    this.else = "Something Else"
}
Test.prototype.something = function () {
    console.info(this);       
}
Test.prototype.somethingElse = function () {
    console.info(this.else);       
}

var test4 = new Test();
test1.somethingElse() // Logs "Something Else"

(请注意,如果您如上所述从构造函数返回您自己的对象,那么您将无法再访问原型对象上的方法。)

另请注意,每次调用构造函数时,它都会返回一个新对象。您可以将参数传递给构造函数(就像您可以使用任何其他函数一样)并使用它们来自定义返回的对象:

var Test = function(else) {
    this.else = else;
}
Test.prototype.somethingElse = function () {
    console.info(this.else);       
}

var test1 = new Test("Something else");
var test2 = new Test("Something else again");

test1.somethingElse(); // Logs "Something else"
test2.somethingElse(); // Logs "Something else again"
于 2013-01-08T10:39:25.140 回答
0

您遇到的问题是因为this引用了一个对象,但Test()不是一个对象;这只是一个功能。拥有Test()的对象是Window对象(因为 Test 在全局范围内),因此这就是您this从内部引用时返回的内容Test()

您可能想尝试这样的事情:

var testObj = {
    Test : function() {
        var that = this;
            return {
            something: function() {
                console.info(that);
            }
        }
    }
}

现在您可以调用testObj.Test();,您将获得对该testObj对象的引用。

希望能澄清一点。

于 2013-01-08T10:12:40.687 回答