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开发指南》

  • 相关阅读:
    Notepad++使用-如何导出/导入配置文件
    浏览器清除页面JS文件缓存的方法
    如何搭建一个简易的Web框架
    Visual Studio Code插件Code Runner中文乱码问题
    【笔记】做一个winform时遇到的坑
    【笔记】使用腾讯地图坐标转换
    使用js检测用户是否在用微信浏览器浏览网站
    phonegap+百度地图导航(JS版)
    浮躁的人
    【笔记】自动生成一个不重复的字符串
  • 原文地址:https://www.cnblogs.com/hwencc/p/4903554.html
Copyright © 2011-2022 走看看