JavaScript Closures

JavaScript Closures

 

Closures

Scope chain

var global = 1;
function outer() {//函数作用域
    var outer_local = 2;

    function inner() {//一个内部函数inner()has access to all variables
        var inner_local = 3;
        return inner_local + outer_local + global;
    }

    return inner();
}

console.log(outer());//6

从这个示例中可以看到inner()函数可以访问到所有的变量,这就是作用域链的效果。

 

Breaking the chain with a closure

var a = "global variable";
var F = function () {
    var b = "local variable";
    var N = function () {
        //The function N has access to its private space, to the F() function's space, and to the global space.
        var c = "inner local";
        return b;
    };
    return N;
};

The function N has access to its private space, to the F() function's space, and to the global space. So, it can see b. Since F() is callable from the global space (it's a global function), you can call it and assign the returned value to another global variable. The result: a new global function that has access to the F() function's private space:

var inner = F();
var b = inner();
console.log(b);//local variable

另一个闭包的例子:

var inner; // placeholder
var F = function () {
    var b = "local variable";
    var N = function () {
        return b;
    };
    inner = N;
};
F();

A new function, N(),is defined inside F() and assigned to the global inner. During definition time, N() was inside F(), so it had access to the F() function's scope. inner() 

will keep its access to the F() function's scope, even though it's part of the global space:

var b = inner();
console.log(b);//local variable

 

A definition and closure

Every function can be considered a closure. This is because every function maintains a secret link to the environment (the scope) in which it was created. But, most of the time this scope is destroyed unless something interesting happens (as shown above) that causes this scope to be maintained.

Based on what you've seen so far, you can say that a closure is created when a function keeps a link to its parent scope even after the parent has returned. And, every function is a closure because, at the very least, every function maintains access to the global scope, which is never destroyed.

 

再看一个闭包的例子,这个闭包的例子是有关函数的参数的:

Function parameters behave like local variables to this function(函数的参数就像函数作用域中的本地变量一样), but they are implicitly(隐式的) created (you don't need to use var for them). You can create a function that returns another function, which in turn returns its parent's parameter:

function F(param) {
    var N = function () {
        return param;
    };
    param++;
    return N;
}

var inner = F(123);
var result = inner();
console.log(result);

Notice how param++was incremented after the function was defined and yet, when called, inner() returned the updated value. This demonstrates that 

the function maintains a reference to the scope where it was defined, not to the variables and their values found in the scope during the function definition.

 

Closures in a loop

function F() {
    var arr = [], i;
    for (i = 0; i < 3; i++) {
        arr[i] = function () {
            return i;
        };
    }
    return arr;
}

var arr = F();
console.log(arr[0]());//3
console.log(arr[1]());//3
console.log(arr[2]());//3

三次循环,每次循环保存当前循环的变量i,但从结果来看,没有得到我们想要的效果:

程序应该这样改:

function F() {
    var arr = [], i;
    for (i = 0; i < 3; i++) {
        arr[i] = (function (x) {
            return function () {
                return x;
            };
        }(i));
    }
    return arr;
}

var arr = F();
console.log(arr[0]());//0
console.log(arr[1]());//1
console.log(arr[2]());//2

Here, instead of just creating a function that returns i, you pass the ivariable's current value to another immediate function. In this function, ibecomes the local value x, and xhas a different value every time.

 

Alternatively(另外), you can use a "normal" (as opposed to an immediate) inner function to achieve the same result. The key is to use the middle function to "localize" the value of iat every iteration:

function F() {
    function binder(x) {
        return function () {
            return x;
        };
    }

    var arr = [], i;
    for (i = 0; i < 3; i++) {
        arr[i] = binder(i);
    }
    return arr;
}

var arr = F();
console.log(arr[0]());//0
console.log(arr[1]());//1
console.log(arr[2]());//2

 

Getter/Setter-Closures 

var getValue, setValue;
(function () {
    var secret = 0;
    getValue = function () {
        return secret;
    };
    setValue = function (v) {
        if (typeof v === "number") {
            secret = v;
        }
    };
}());

console.log(getValue());//0
setValue(123);
console.log(getValue());//123

In this case, the function that contains everything is an immediate function. It defines setValue()and getValue()as global functions, while the secretvariable remains local and inaccessible directly.

 

Iterator-Closures 

The last closure example (also the last example in the chapter) shows the use of a closure to accomplish an iterator functionality.

function setup(x) {
    var i = 0;
    return function () {
        return x[i++];
    };
}

var next = setup(['a', 'b', 'c']);
console.log(next());//a
console.log(next());//b
console.log(next());//c

For this example, let's just use a simple array and not a complex data structure. Here's an initialization function that takes an input array and also defines a secret pointer, i, that will always point to the next element in the array.

========END========

转载于:https://my.oschina.net/xinxingegeya/blog/403391

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值