文档章节

JavaScript Closures

秋风醉了
 秋风醉了
发布于 2015/04/18 19:39
字数 921
阅读 70
收藏 0

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========

© 著作权归作者所有

秋风醉了
粉丝 252
博文 532
码字总数 405694
作品 0
朝阳
程序员
私信 提问
「译」javascript 的 12 个怪癖(quirks)

原文:12 JavaScript quirks 译文:「译」javascript 的 12 个怪癖(quirks) 译者:justjavac 实际上 javascript 是一个相当简洁的语言,但是也难免会有一些怪癖(quirks)。 本章是 javasc...

justjavac
2013/04/16
338
0
5道 JavaScript 练习题

在深入理解JavaScript系列(20):《你真懂JavaScript吗?》答案详解中最后的看到的一些练习题,并尝试自己做且记录下来。 找出数字数组中最大的元素(使用Math.max函数) 转化一个数字数组为...

_我已经从中二毕业了
09/29
0
0
JavaScript Functions

JavaScript Functions Parameters js的函数可以接受多个参数 Predefined functions(预定义的函数) There are a number of functions that are built into the JavaScript engine and are ......

秋风醉了
2014/07/16
52
0
hey man,你认为你懂Js?

Quick test for real understanding of JavaScript core beyond closures and scopes. Here five small scripts. Try to answer what will be alerted in each case without running them in......

out_lier
2014/04/03
229
2
web前端学习:深入理解JS闭包

第一部分:初遇闭包 http://www.runoob.com/js/js-function-closures.html 什么是闭包?闭包有什么作用?这是我遇到闭包时的第一反应。 闭包在JavaScript高级程序设计(第3版)中是这样描述:...

IT智云编程
2018/07/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Centos6.6 安装ffmpeg视频工具

1.安装前置工具 yum -y install gcc cc cl libmpc*//后续失败的话,自己补充自己的缺少的包 2.安装yasm 1)下载wget http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz...

小海bug
26分钟前
4
0
电商的支付风控怎么玩?

qwfys
31分钟前
6
0
用什么来做用户行为分析?七个实用工具推荐给你

当企业进入数据化管理阶段之后,就不得不对用户进行行为数据分析,当然其他的包括用户画像、趋势分析等等,都是现在企业经常要进行的营销分析,因此选一个好的数据分析工具是很重要的。 而现...

朕想上头条
32分钟前
5
0
Java mysql连接

import java.sql.DriverManager; import java.sql.SQLException; import com.mysql.jdbc.Connection; public class T { public static void main(String[] args) throws SQLException, Insta......

林词
32分钟前
4
0
Select 选择器 的一些官网没有的用法

一、拼接字符串 <el-option v-for="(item, index) in reagentOptions" :key="index" :label="item.sjlxmc+' '+item.sjbm" :va......

沉迷代码我爱学习
33分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部