我在全球范围内定义了以下模块:
var module = (function () {
console.log(this);
this.fn = function () {
console.log(this);
}
return this;
})();
http://www.quirksmode.org/js/this.html:
In JavaScript |this| always refers to the “owner” of the function we're executing, or rather, to the object that a function is a method of.
第一次调用console.log
会将Window
记录为this
的值,我理解。但是,对console.log
的第二次调用也是如此。
由于this
是指该函数的所有者,为什么module.fn
会记录Window
而不是module
?
当我致电fn
时,我仍然需要写module.fn
,我无法写Window.fn
。由于this
引用Window
,我觉得这很令人困惑。
编辑:我忘记在我的例子中返回this
。
答案 0 :(得分:4)
由于这是指函数的所有者,为什么module.fn会记录Window而不是模块?
外部函数的返回值为window
,因为它不会在任何特定上下文中调用,因此module
最终也会成为window
。
似乎你应用模块模式的方式是错误的。它应该返回在其余代码中使用的公共接口:
var module = (function () {
console.log(this);
// public interface
return {
fn: function () {
console.log(this);
}
}
})();
module.fn(); // "Object {fn: function}"
答案 1 :(得分:2)
您制作封闭范围并将module
设置为从该范围返回时,您的模式是错误的:
// This is the design pattern:
var module = (function () {
var module = {};
var localVar = 1;
module.moduleVar = 2;
module.fn = function () {
console.log(this);
}
return module;
})();
console.log(module.fn); // function() { console.log(this) ;}
console.log(module.moduleVar); // 2
console.log(module.localVar); // undefined
答案 2 :(得分:2)
在您的示例中,全局对象接收fn
。对于浏览器,它是window
对象。那是因为你在没有特定上下文的情况下调用函数(有效地构建一个新的作用域)。
最后,您的module
对象只是对window
的引用(因为return this;
)。
this
?在JavaScript中,this
是当前上下文,即在特定时间调用函数的对象。 不该功能的“持有者”。你总是可以从其他对象“窃取”这个方法,并apply
(字面意思)将它移植到你自己的对象中。
假设您想要出于某种原因对arguments
对象进行切片。它看起来就像一个数组,但它不是一个数组。 arguments.slice(2,4)
不起作用(假设ECMAScript <5)。怎么办?
Array.prototype.slice.apply(arguments, [2,4]);
你需要从em原型中窃取 slice
函数,并在你的参数上使用if。在slice
调用中,“this”是特定时间的参数对象。
你的工作是return
模块对象。你不想弄乱上下文。只要您不直接在模块对象上应用该函数,它就不相关了。
最简单的解决方案是最简单的。
var module = (function() {
// do something internally, great for "private" stuff
// then return the "public" interface
return {
doSomething: function() {
// do something
},
introduce: function() {
console.log(this);
}
};
})();
module.introduce(); // Object {doSomething: function, introduce: function}
module.doSomething();
另一种方式。
或者,如果你真的想,可以使用this
来完成你的工作。
var module = {};
(function(){
this.doSomething = function() {
// do something
};
this.introduce = function() {
console.log(this);
};
}).apply(module);
module.introduce(); // Object {doSomething: function, introduce: function}
module.doSomething();
请注意,这几乎等于“新”电话。
有更多同样有效的方法,但第一个提出的方法经常使用,非常清楚。无论如何,一切都取决于你的代码约定。