为什么函数内部的自调用函数不能获得JavaScript中外部函数的作用域?
var prop = "global";
var hash = {
prop: "hash prop",
foo: function(){
console.log(this.prop);
(function bar(){
console.log(this.prop);
})();
}
};
var literal = {
prop: "object"
};
hash.foo();
// hash prop
// global
hash.foo.call(literal);
// object
// global
看起来改变外部函数的范围对内部自调用函数的范围没有影响。
PS:问题不在于如何改变内部功能的范围。但是,在“Javascript语言”视角下,正确的解释是什么?默认情况下,所有自执行函数都具有“全局”范围吗?如果是这样,为什么?
答案 0 :(得分:7)
您的问题是this
及其引用的内容:
foo: function(){
console.log(this.prop);
(function bar(){
console.log(this.prop); <--- this does not reference to foo here, but instead it refers to the window object
})();
}
您需要保留对外this
:
foo: function(){
console.log(this.prop);
var that = this;
(function bar(){
console.log(that.prop); <--- tada!
})();
}
<强>更新强>
一些解释。这是关于JavaScript在调用函数时如何确定上下文的。
function Test() {
this.name = "Test";
this.bar = function() { console.log("My name is: "+ this.name);}
}
function Blub() {
this.name = "Blub";
this.foo = function() { console.log("My name is: " + this.name);}
}
var a = new Test();
var b = new Blub();
// this works as expected
a.bar(); // My name is: Test
b.foo(); // My name is: Blub
// let's do something fun
a.foo = b.foo; // make an educated guess what that does...
a.foo() // My name is: Test
咦?我们不是在引用Blub的method
吗?没有,我们没有。我们引用了Blub的未绑定function
。
JavaScript绑定.
(点),并根据它确定this
的值应该是。
由于你没有在一个对象上调用你的匿名函数(因此没有.
),它将使this
引用全局对象,在浏览器的情况下,它是窗口对象
另一个例子(人们可能认为这会起作用):
var str = "Hello World";
var ord = str.charCodeAt; // let's make a little shortcut here.... bad idea
ord(0) // no dot...
而不是str
中的字符代码,我们得到全局对象中的字符代码,当然这不是字符串,因此charCodeAt
调用toString
会导致"[object DOMWindow]"
{ {1}}
答案 1 :(得分:1)
当您调用内部函数时,您没有将任何对象应用为this
上下文,因此默认情况下this
设置为window
。如果你想用与外部函数相同的this
调用闭包,你必须这样做:
(function bar(){
console.log(this.prop);
}).call(this);
或者:
var that = this;
(function bar(){
console.log(that.prop);
})();