繁体   English   中英

不了解Javascript中的范围

[英]Not understanding scope in Javascript

我不太明白这段代码。

$('div').click((function () { 
    var number = 0;
    return function () {
        alert(++number);
    };
})());

我的理解是:

  • 定义匿名函数并将其分配给单击处理程序。

  • 当我单击div时,将调用此函数。

该功能的作用是:

  • 定义变量number = 0

  • 返回++number

那么为什么每次点击时警报的数量会增加? 每次点击都不应该将number重置为0?

在这里你有一个自动调用函数 ,它返回一个函数。 注意最后的括号:

(function () { 
    var number = 0;
    return function () {
        alert(++number);
    };
})()

所以click处理程序的回调只是返回的内部函数

function () {
    alert(++number);
};

此内部函数可以访问变量number ,该变量在外部函数的范围内。

所以你的代码也可以写成如下:

function outerFunction() {
    var number = 0;
    return function () {
        alert(++number);
    };
};

var innerFunction = outerFunction();

$('div').click(innerFunction);

如果我们为匿名函数使用(丑陋)名称,则可以将代码重写为:

$('div').click((function makeIncrementer() {
    var number = 0;
    return function incrementAndAlert() {
        alert(++number);
    };
})());

保留类似语义的更详细代码将是:

var makeIncrementer = function() {
    var number = 0;
    return function() { alert(++number); };
};

var incrementAndAlert = makeIncrementer(); // function() { alert(++number); }

$('div').click(incrementAndAlert);

makeIncrementer是一个函数,在调用时,在其作用域中定义一个number变量,并返回一个函数 - 注意makeIncrementer不递增,也不警告number变量,而是返回另一个函数。

现在incrementAndAlert绑定到这个返回的函数

function() { alert(++number); }

它捕获makeIncrementernumber变量,这使它能够在$('div')点击触发的incrementAndAlert调用之间保持number的状态。

这不是一个“答案”,但希望它会以不同的方式来看待问题。


首先,请注意JavaScript函数只是对象,因此只是可以绑定到变量的值。 因此,

$('div').click((function () { 
    var number = 0;
    return function () {
        alert(++number);
    };
})());

可以通过简单的表达式替换重写为

var f = function () { 
    var number = 0;
    return function () {
        alert(++number);
    };
};
// $('div').click((f)()); and when removing extra parenthesis ->
$('div').click(f());

然后,经过一次简单的表达式替换

var g = f()
$('div').click(g);

应该清楚的是,首先调用(外部)函数f ,它是用作处理程序的结果(内部函数)值g

除了引入变量之外,上述替换在语义上等同于原始代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM