如何从JavaScript模块中访问“this”?

如何从JavaScript模块中访问“this”?,javascript,module,this,Javascript,Module,This,我试图理解如何最好地使用JavaScript模块模式。我的问题是,似乎无法从模块内部引用该模块,因为它被设置为窗口对象 我有一个简单的测试代码: var Test = function() { var that = this; return { something: function() { console.info(that); } } } var test1 = Test(); test1.something

我试图理解如何最好地使用JavaScript模块模式。我的问题是,似乎无法从模块内部引用该模块,因为它被设置为窗口对象

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

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

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

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

var test2 = Test();
test2.something();
test1和test2都打印对窗口对象的引用,而不是模块本身

你知道如何更改它,以便我在模块中有一个有效的this吗?

如果你这样做了

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();
var testObj = {
    Test : function() {
        var that = this;
            return {
            something: function() {
                console.info(that);
            }
        }
    }
}
希望这对你有所帮助

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();
var testObj = {
    Test : function() {
        var that = this;
            return {
            something: function() {
                console.info(that);
            }
        }
    }
}

希望这对您有所帮助。您遇到的问题是,这指的是一个对象,而Test不是一个对象;这只是一个函数。拥有测试的对象是窗口对象,因为测试在全局范围内,所以当您从测试中引用它时,您会得到它

您可能想尝试以下方法:

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();
var testObj = {
    Test : function() {
        var that = this;
            return {
            something: function() {
                console.info(that);
            }
        }
    }
}
现在可以调用testObj.Test;您将获得对testObj对象的引用


希望这能澄清一些问题。

您遇到的问题是,这指的是一个对象,而Test不是一个对象;这只是一个函数。拥有测试的对象是窗口对象,因为测试在全局范围内,所以当您从测试中引用它时,您会得到它

您可能想尝试以下方法:

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();
var testObj = {
    Test : function() {
        var that = this;
            return {
            something: function() {
                console.info(that);
            }
        }
    }
}
现在可以调用testObj.Test;您将获得对testObj对象的引用


希望这能澄清一些问题。

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

JavaScript构造函数 如果您编写了一个函数并在其前面使用new关键字调用它,那么该函数将作为构造函数调用

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

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

如果前面没有使用new关键字调用它,那么它就像一个常规函数一样被调用,这意味着在它内部对该函数的任何引用都引用了该函数所属的对象,在没有任何其他内容的情况下,该对象将是全局对象,在web浏览器中是窗口

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

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"

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

JavaScript构造函数 如果您编写了一个函数并在其前面使用new关键字调用它,那么该函数将作为构造函数调用

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

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

如果前面没有使用new关键字调用它,那么它就像一个常规函数一样被调用,这意味着在它内部对该函数的任何引用都引用了该函数所属的对象,在没有任何其他内容的情况下,该对象将是全局对象,在web浏览器中是窗口

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

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"

迂腐的注释:至少我不认为您的代码是JavaScript模块模式的示例。你现在有一个常规的构造函数,叫做Test。或者更确切地说,你现在有一个看起来像构造函数的函数,叫做Test,但是因为你没有在前面用new关键字调用它,所以它不会被作为构造函数调用。迂腐的注记:我不认为你的代码是
至少是JavaScript模块模式。你现在有一个常规的构造函数,叫做Test。或者更确切地说,你现在有一个看起来像是构造函数的函数,叫做Test,但是因为你没有在前面用new关键字调用它,所以它没有被作为构造函数调用。调用new Test而不是Test有什么缺点吗?@Laurent No,不是真的。它将设置这个,这可能是可取的,但其他人更喜欢其他方式调用新测试而不是只调用测试有什么缺点吗?@Laurent不,不是真的。它将设定这一点,这可能是可取的,但其他人更愿意这样做