Javascript作用域/闭包:为什么我可以在这里访问内部变量?

Javascript作用域/闭包:为什么我可以在这里访问内部变量?,javascript,scope,closures,Javascript,Scope,Closures,我目前正在从事一个相对简单的项目,并发现了一些东西: var test = (function() { var internal = 5; return { init: function() { $(document).on('click', function() { alert(internal); }); } }; }()); test.init(); 我

我目前正在从事一个相对简单的项目,并发现了一些东西:

var test = (function() {
    var internal = 5;
    return {
        init: function() {
            $(document).on('click', function() {
                alert(internal);
            });
        }
    };
}());
test.init();
我认为闭包和javascript作用域(据我所知)意味着函数只能访问它自己的变量,以及它上面的1级变量。那么,这是为什么?当我点击文档时,我得到一个“5”的警告,我希望得到未定义的

下面是一个JSFIDLE,显示了我正在做的事情:

我认为闭包和javascript作用域(据我所知)意味着函数只能访问它自己的变量,以及它上面的1级变量

不,它的级别都高于它。事实上,这就是全局变量在JavaScript中的工作方式;它们只是闭包的一个例子

那么,这是为什么

当JavaScript引擎需要解析符号时,它首先(松散地)查看符号出现的执行上下文(在本例中,是通过调用您在上传递的匿名函数创建的)。如果没有找到匹配的变量,它会查看围绕该变量的执行上下文(在本例中,是通过调用
init
创建的)。如果在那里找不到它,它会查看下一个(通过调用最外层的匿名函数创建的)。如果没有,则进入下一级,直到到达全局执行上下文

关于闭包的更多信息(在我的博客上):

请注意,我一直在说“…由上面的调用创建”。这是一个关键点:当程序运行时,可以(几乎总是)为给定范围创建多个执行上下文。考虑:

function foo(name) {
    return function() {
        alert(name);
    };
}
(这只是两个级别,但它适用于任意多个级别。)

foo
在被调用时,创建并返回一个函数,该函数在被调用时向我们显示创建该函数时传递给
foo
的名称:

调用
foo
创建执行上下文。函数
foo
creates对上下文中包含该调用变量的部分有一个持久引用(规范称之为“变量绑定对象”)。在
foo
返回后,绑定对象仍然存在,这就是为什么当我们调用
foo
创建的函数时,它仍然可以访问相关的
name
变量

重要的是要记住,闭包并不是获取变量值的副本。他们得到了对那个变量的持久引用。这就是为什么这样做的原因:

function foo(a) {
    return function() {
        alert(++a);
    };
}
var f = foo(0);
f(); // 1
f(); // 2
f(); // 3
我认为闭包和javascript作用域(据我所知)意味着函数只能访问它自己的变量,以及它上面的1级变量

不,它的级别都高于它。事实上,这就是全局变量在JavaScript中的工作方式;它们只是闭包的一个例子

那么,这是为什么

当JavaScript引擎需要解析符号时,它首先(松散地)查看符号出现的执行上下文(在本例中,是通过调用您在上传递的匿名函数创建的)。如果没有找到匹配的变量,它会查看围绕该变量的执行上下文(在本例中,是通过调用
init
创建的)。如果在那里找不到它,它会查看下一个(通过调用最外层的匿名函数创建的)。如果没有,则进入下一级,直到到达全局执行上下文

关于闭包的更多信息(在我的博客上):

请注意,我一直在说“…由上面的调用创建”。这是一个关键点:当程序运行时,可以(几乎总是)为给定范围创建多个执行上下文。考虑:

function foo(name) {
    return function() {
        alert(name);
    };
}
(这只是两个级别,但它适用于任意多个级别。)

foo
在被调用时,创建并返回一个函数,该函数在被调用时向我们显示创建该函数时传递给
foo
的名称:

调用
foo
创建执行上下文。函数
foo
creates对上下文中包含该调用变量的部分有一个持久引用(规范称之为“变量绑定对象”)。在
foo
返回后,绑定对象仍然存在,这就是为什么当我们调用
foo
创建的函数时,它仍然可以访问相关的
name
变量

重要的是要记住,闭包并不是获取变量值的副本。他们得到了对那个变量的持久引用。这就是为什么这样做的原因:

function foo(a) {
    return function() {
        alert(++a);
    };
}
var f = foo(0);
f(); // 1
f(); // 2
f(); // 3

Javascript的作用域是静态的。当您编写函数时,您将可以访问函数中所有可用的变量,因为这些变量可以从您访问函数的位置访问

var a = 10;
function foo() {
    // now i have access in a
    var b = 20;
    // i have access to both a and b
    function bar() {
        // still have access to both a and b
        var c = 30;
        // any more nested function will have access to a,b and c
    }
}

Javascript的作用域是静态的。当您编写函数时,您将可以访问函数中所有可用的变量,因为这些变量可以从您访问函数的位置访问

var a = 10;
function foo() {
    // now i have access in a
    var b = 20;
    // i have access to both a and b
    function bar() {
        // still have access to both a and b
        var c = 30;
        // any more nested function will have access to a,b and c
    }
}

我相信变量可以在页面内的任何地方访问。他们的范围是整个页面查看更多关于如何关闭的详细信息work@AlienArrays:
test
函数中未定义
internal
<代码>测试最终引用了匿名函数返回的对象。我相信变量可以在页面内的任何位置访问。他们的范围是整个页面查看更多关于如何关闭的详细信息work@AlienArrays:
test
函数中未定义
internal
<代码>测试最终引用匿名函数返回的对象。