zoukankan      html  css  js  c++  java
  • JavaScript作用域以及闭包(一)

    第二篇链接 JavaScript作用域以及闭包(二)

    JavaScript作用域

    在学习JavaScript的过程中不可避免会遇到闭包问题,其实闭包概念并不难理解,只要理解了JavaScript中作用域概念,那么就很容易理解什么是闭包了。

    JavaScript没有块级作用域

    //没有块级作用域
    if(true){
    var sm = "hello";
    }

    console.log(sm); //hello

     

    JavaScript的作用域是由函数"决定"的,JavaScript的执行环境只有两种——全局和局部(函数)。

    作用域链,在JavaScript中标识符的解析是沿着作用域一级级地搜索标识符的过程。搜索过程始终以作用域链的前端开始,然后逐级向后回溯,直到找到标识符(找不到通常会报错)

    //作用域链搜索
    var name = "json";
    (function(){
    console.log(name); //undefined
    var name = "hello";
    })();

     

    这个例子之所以输出的是'undefined'是因为JavaScript的作用域链机制,在执行console语句时,首先会搜索匿名函数内部的作用域,而且恰好找到了name("hello")这个变量,所以外层的name变量被屏蔽了。但执行到console语句时,name还没被定义(或者说是初始化),所以得到的是undefined值。

    闭包

    那么明白了JavaScript的作用域概念后,所谓的闭包也就不难理解了。通俗地讲JavaScript中每个函数都是闭包(上下文环境:全局),但通常嵌套的函数更能体现闭包特性。下面简单说明下:

    按JavaScript作用域链的机制,被嵌套在里面的函数(简称:里函数)是可以访问到其外部的函数(外函数)的变量的。这个很容易理解。而闭包就是,在返回里函数的时候,不仅会返回函数本身还会把函数的上下文环境一并返回。这就是闭包的本质。

    //引用自'JavaScript语言精粹'
    var quo = function(status){
    return {
    get_status:function(){
    return status;
    }
    };
    };

    var myQuo = quo("amazed");

    console.log(myQuo.get_status()); //amazed

     

    "即使quo已经返回了,但get_status方法依然享有访问quo对象status属性的特权。get_status方法并不是访问该参数的一个副本,它访问的就是该参数本身。这是可能的,因为该函数可以访问它被创建时所处的上下文环境。这被称为闭包"

      

    下面这段代码比上面那段更为通俗,通过下面的例子对闭包可以有进一步的理解:

    //引用自'nodejs开发指南'
    var smClosure = function(){
    var count = 0;
    var get = function(){
    count++;
    return count;
    };
    return get;
    }

    var sm1 = smClosure();
    var sm2 = smClosure();
    console.log(sm1()); //1
    console.log(sm2()); //1
    console.log(sm1()); //2
    console.log(sm1()); //3
    console.log(sm2()); //2

     

    sm1,sm2分别调用了smClosure()函数,生成了两个闭包实例,他们内部引用的count分别属于各自的执行环境。这就是所谓的返回内部函数时,不仅会返回函数本身还会一并返回其上下文环境的意思。

    扩展:

    关于作用域,JavaScript的变量和函数声明都会被存储到执行上下文的变量对象中,即声明提升。函数声明的优先级高于变量声明的优先级,但不会覆盖变量赋值。

    而命名函数表达式的标识符(即函数名)在外部作用域是无效的,只在函数作用域内有效。

    var sm = function something(){
    console.log(typeof something); //function
    }
    sm();
    console.log(typeof something); //undefined
    console.log(typeof sm); //function

    参考

    《JavaScript高级程序设计》

    《JavaScript语言精粹》

    《nodejs开发指南》

  • 相关阅读:
    python用win32com模拟浏览器
    python判断输入的字符串是否为数字
    phpwind9.0去掉头部版权信息 Powered by phpwind
    Python批量查询网站收录
    结巴分词 python中文分词
    phpwind 9.0 RC版[20121108],伪静态无效的问题
    [转]LINQ: Building an IQueryable provider series
    获取鼠标选择的文本内容之JavaScript代码
    M2级遍历和范围Range
    转:浏览器的用户代理字符串
  • 原文地址:https://www.cnblogs.com/hwencc/p/4903554.html
Copyright © 2011-2022 走看看