Javascript中自我调用功能的范围

sha*_*moh 2 javascript

为什么函数内部的自调用函数不能获得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
Run Code Online (Sandbox Code Playgroud)

看起来改变外部函数的范围对内部自调用函数的范围没有影响.

PS:问题不在于如何改变内部功能的范围.但是,在"Javascript语言"视角下,正确的解释是什么?默认情况下,所有自执行函数都具有"全局"范围吗?如果是这样,为什么?

Ivo*_*zel 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
    })();
}
Run Code Online (Sandbox Code Playgroud)

你需要保持对外部的引用this:

foo: function(){
    console.log(this.prop);

    var that = this;
    (function bar(){
        console.log(that.prop);  <--- tada!
    })();
}
Run Code Online (Sandbox Code Playgroud)

更新
一些解释.这就是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
Run Code Online (Sandbox Code Playgroud)

咦?我们不是参考methodBlub的吗?没有,我们没有.我们引用了function未经约束的Blub.

JavaScript绑定.(点)并基于它决定this应该是什么值.

由于您没有在对象上调用匿名函数(因此没有.),因此它将this引用全局对象,在浏览器的情况下,它是窗口对象.

另一个例子(人们可能认为这会起作用):

var str = "Hello World";
var ord = str.charCodeAt; // let's make a little shortcut here.... bad idea

ord(0) // no dot... 
Run Code Online (Sandbox Code Playgroud)

而不是str我们得到的全局对象中的char代码,当然不是一个字符串所以charCodeAt调用toString导致"[object DOMWindow]"