我正试图围绕构建自定义JavaScript库。我已经阅读了很多关于模块模式的内容,还阅读了Crockford关于私人和公共成员的文章。我知道什么是立即调用的函数表达式以及我们为什么要这样做
var myLib = (function() {
}())
然而,在某些情况下,我仍然有点失去关于范围和关闭的一般情况。我遇到的具体问题是:
为什么以下示例会警告DOMWindow而不是myLib对象? http://jsfiddle.net/slavo/xNJtW/1/
如果您能够解释该示例中所有方法中“this”所指的内容以及原因,那就太棒了。
答案 0 :(得分:4)
在声明的任何函数内(任何地方)并调用如下this
将是窗口对象
function anyFunc(){
alert(this); // window object
}
anyFunc();
var anyFunc2 = function(){
alert(this); // window object
}
anyFunc2();
如果要创建私有函数并访问“myObject”实例,可以使用以下任一方法
一
module = (function () {
var privateFunc = function() {
alert(this);
}
var myObject = {
publicMethod: function() {
privateFunc.apply(this); // or privateFunc.call(this);
}
};
return myObject;
}());
module.publicMethod();
两个
module = (function () {
var _this; // proxy variable for instance
var privateFunc = function() {
alert(_this);
}
var myObject = {
publicMethod: function() {
privateFunc();
}
};
_this = myObject;
return myObject;
}());
module.publicMethod();
这些是您的问题的解决方案。我建议使用基于原型的对象。
编辑:
您可以使用第一种方法。
事实上,myObject
与privateFunc
的范围相同,您可以直接在函数内使用
var privateFunc = function() {
alert(myObject);
}
真实情况是你可以使用代理this
如下所示。您也可以使用call
。
Module = function () {
var _this; // proxy variable for instance
var privateFunc = function() {
alert(this + "," + _this);
}
this.publicMethod = function() {
privateFunc(); // alerts [object Window],[object Object]
privateFunc.call(this); // alerts [object Object],[object Object]
}
_this = this;
return this;
};
var module = new Module();
module.publicMethod();
答案 1 :(得分:0)
您需要明确声明myPrivateMethod是myLib的成员:
function MyLib ()
{
this._myPrivateField = "private";
this._myPrivateMEthod = function ()
{
alert(this); // Alerts MyLib function;
}
}
var libObject = new MyLib();
请记住,如果不使用机箱技术,JavaScript中的任何内容都不会真正私密!
更好的方法就是这样:
function MyLib(instanceName)
{
this.name = instanceName;
}
MyLib.prototype.myPrivateFunction()
{
alert(this);
}
在此之后调用您的方法:
var libObject = new MyLib();
libObject.myPrivateMethod(); // Alerts info about libObject.
答案 2 :(得分:-1)
关于模块模式需要记住的是它运行一次并完成。仍然可以调用的方法是闭包。在创建模块时,“this”指向窗口并被其值替换。
答案 3 :(得分:-2)
在你的联系小提琴中,"这个"关键字永远不会被" new"关键字或其他上下文更改,因此它仍然引用全局窗口对象。
编辑:澄清