zoukankan      html  css  js  c++  java
  • JavaScript中的作用域和闭包

    首先强烈安利《你不知道的JavaScript》,JS初学者进阶必读。

    对于从C++、Java等静态语言转向JavaScript的初学者(比如我)来说,JS一些与众不同而又十分要紧的特性使得它显得十分诡异而难以捉摸,为此必须下一番大力气,一边啃书一边实践将这些概念彻底搞懂,然后才谈得上进一步学习前端姿势。(注:本文里的JS以ECMAScript 5(ES5)为准,ES6的新特性我也是刚刚接触,希望今后能与大家一起学习探讨。)

    熟悉Java的童鞋在初学JS时,必须要牢记一点:

    JS中没有块级作用域!

    {
        var test=10;
    }
    console.log(test);    // 控制台输出:10

    纳尼?是不是看着很别扭?还有更坑爹的:

    var obj={
        test:10,
        myFunc:function(){
            console.log(test); 
        }
    };
    obj.myfunc();   // 出错,或者IDE直接报警了

    同一个对象,自己的函数都不认自己的属性了?

    还真是。

    对于初学者而言,可以这样认为:除了全局作用域之外,JS只有一种作用域,即函数作用域。(try catch{}语句也可以定义作用域,不过目前为止我还没实际用过)

    也就是说,写在函数体内的变量,只要不是嵌套在更深层的函数里,就是处在同一作用域的,“互相可见”;而其他的花括号,不管是for后跟的,if后跟的,还是对象字面量的,一概“不作数”,起不到定义作用域的效果,变量声明写在那些花括号的里面或外面都一样。

    那位于嵌套的函数里的作用域呢?它们享有“单向透明”的特权,即:在较内层次的作用域内可以访问较外层次作用域里的变量,反之则不行。

    function outerFunc(){
        for(var i=0;i<10;i++){doSomething;}
        console.log(i); // 控制台输出10,因为i位于outerFunc的作用域
        var outer = 10;
        function innerFunc(){
            var inner = outer; // 内层作用域可以访问外层作用域里的变量
        }
        console.log(inner); // 报错,外层作用域访问不到内层作用域里的变量
    }

    再来分析上一个例子。我们试图在myFunc的作用域内部访问test,然而test并不是一个“与myFunc位于同一个对象作用域”的变量,事实上根本不存在“对象作用域”这回事,test是obj的一个属性,不是一个“独立”的变量,要访问test只能通过点运算符obj.test或obj["test"],哪怕是在myFunc内部。当然,myFunc内部可以访问到obj这个位于外层作用域的变量,没有问题。于是将代码改写如下:

    var obj={
        test:10,
        myFunc:function(){
            console.log(obj.test); 
        }
    };
    obj.myfunc();   // 10

    既然在内层作用域里可以访问外层作用域,那么就产生了一个有趣的现象,叫做“闭包”。制造一个闭包只需要两步:

    1.在内层函数里引用外层函数的变量

    2.将内层函数作为外层函数的返回值返回出去

    function outer(){
        var test = 10;
        var inner = function(){
            console.log(test++);
        };
        return inner;
    }
    
    var myFunc = outer(); // 将outer的返回值(inner函数)赋给myFunc
    myFunc(); // 10
    myFunc(); // 11
    myFunc(); // 12

    这个被返回的inner函数就是一个闭包。虽然outer函数运行结束了,但它的内部变量test因为被闭包引用,所以并没有被销毁,而是被保存了起来,并且可以通过闭包继续操作。当然,外界永远无法访问test这个变量,它成了inner(以及myFunc)所指向的函数的“私有变量”。

  • 相关阅读:
    【C++ Primer Chapter 3 总结】Library vector & string Type
    【C++ Primer Chapter 4 总结】左值 & 右值
    【C++ Primer Chapter 6 总结】函数
    mysql添加索引
    注册plsql
    挑战答题小程序
    开源答题小程序
    答题如何防止作弊
    党史知识答题活动小程序复盘整理
    党史学习教育答题活动复盘
  • 原文地址:https://www.cnblogs.com/leegent/p/5377177.html
Copyright © 2011-2022 走看看