快速学会JavaScript中的闭包(2)


上述代码,不报错而是输出 undefined,其原因是:JavaScript的函数在被执行之前,会将其中的变量全部声明,而不赋值。所以,相当于上述实例中,函数在“预编译”时,已经执行了var xo;所以上述代码中输出的是undefined。

注意:我们平时在声明变量时一定要注意!!!还有不要滥用全局变量(在forin循环的时候特别注意)!!!

4、词法作用域是不可逆的,我们可以从下面的例子中看到结果:

// name = undefined
var scope1 = function () {
  // name = undefined
  var scope2 = function () {
    // name = undefined
    var scope3 = function () {
      var name = 'Todd'; // locally scoped
    };
  };
};

--------------------------------------------------------------------------------

前面我们了解了作用域的一些基本知识,我们发现有作用域的存在能帮我们省去不少事,但是于此同时,也给我们带来了很多麻烦,比如说我们想在下面的函数A中,调用函数B,我们该怎么办呢?

function A(){
    function B(){
          //
    }
}

思路:我们给函数B设一个返回值,然后在函数A中调用,代码如下:

function A(){
    function B(){
      console.log("Hello foodoir!");
    }
    return B;
}
var c = A();
c();//Hello foodoir!

这样我们就可以得到我们想要的结果。这样,我们基本上到了一个最简单的闭包形式。我们再回过头分析代码:

(1)定义了一个普通函数A

(2)在A中定义了普通函数B

(3)在A中返回B(确切的讲,在A中返回B的引用)

(4)执行A(),把A的返回结果赋值给变量 c

(5)执行 c() 


把这5步操作总结成一句话:函数A的内部函数B被函数A外的一个变量 c 引用。当一个内部函数被其外部函数之外的变量引用时,就形成了一个闭包。

思考:我们还有没有其他的方法?

思路:使用匿名函数

function A(){
    //匿名函数
    var B = function(x,y) {
        return x+y;
    }
    console.log(B(1,2));//3
    return B(1,2);
}
var c = A();
console.log(c);//3

然而,在Javascript高级程序设计中是这样描述闭包的“闭包是指有权访问另一个函数作用域中的变量的函数”,但是我们看匿名函数的例子,很明显,这种方法不可取!
通过这个例子,能让我们更好的理解闭包。

下面我们再来看下面的几种闭包

demo1:

function fn(){
    var b = "foodoir";
    return function(){
        console.log(b);//foodoir
        return b;
    }
}
//console.log(b);//b is not defined
var result = fn();
console.log(result());//foodoir

demo2:

var n;
function f(){
    var b = "foodoir";
    n = function(){
        return b;
    }
}
f();
console.log(n());//foodoir

demo3:

//相关定义与闭包
function f(arg){
    var n = function(){
        return arg;
    };
    arg++;
    return n;
}
var m = f(123);
console.log(m());//124
//注意,当我们返回函数被调用时,arg++已经执行过一次递增操作了,所以m()返回的是更新后的值。

demo4:闭包中的读取与修改

//闭包中的设置与修改
var getValue,setValue;
(function(){
    var n = 0;
    getValue = function(){
        return n;
    };
    setValue = function(x){
        n = x;
    }
})();
//console.log(n);
console.log(getValue());//0
console.log(setValue());//undefined

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

demo5:用闭包实现迭代效果

//用闭包实现迭代器效果       
function test(x){
    //得到一个数组内部指针的函数
    var i=0;
    return function(){
        return x[i++];
    };
}
var next = test(["a","b","c","d"]);
console.log(next());//a
console.log(next());//b
console.log(next());//c
console.log(next());//d

demo6:循环中的闭包

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/50aabe8ab2e9b052f001118e8494f3da.html