zoukankan      html  css  js  c++  java
  • JavaScript 变量作用域

    一. 变量声明

    变量用var关键字来声明,如下所示:

    var num;
    var a,b;
    var name = "ting";
    var i=0, j=1, k=2;

    用var关键字申明的变量是永久的,用delete运算符删除不起作用。

    var i = 2;
    delete i;
    console.log(i);  //2

    k = 3;
    delete k;
    console.log(k); //报错:ReferenceError: k is not defined.

    JavaScript变量是松散类型的,可以用来保存任何数据类型。并且还可在修改变量的值时改变变量的类型。

    var answer = 10;
    answer = "The answer is: " + 10;
    console.log(answer);                //10
    console.log(typeof answer);         //string

    二. 变量作用域

    变量的作用域是程序中定义这个变量的区域。函数内部声明的变量只在函数内部起作用。声明局部变量一定要使用var关键字声明。

    在函数内部,局部变量作用域高于同名全局变量。

    var i = 99;
    function foo() {
        var i = 100;
        console.log(i);  //100(使用局部变量)
    }
    foo();
    console.log(i);      //99(使用全局变量)

    声明局部变量未使用var关键字,该变量会暴露在全局环境中,与现有的全局变量冲突。如下代码中,函数内部的变量a未使用var关键字,与全局环境中的a冲突,在全局环境中调用a。

    var a = 5;
    function foo() {
        a = 10;
        b = 15;
        console.log(a);  //10
        console.log(b);  //15
    }
    foo();
    console.log(a);      //10
    console.log(b);      //15

    变量在未声明的情况下被初始化,会被添加到全局环境。

    var add = function(a,b) {
        var sum = a + b;
        return sum;
    }
    var res = add(2,3);
    console.log(res);       //5
    console.log(sum);       //ReferenceError: sum is not defined

    var add = function(a,b) {
        sum = a + b;
        return sum;
    }
    var res = add(2,3);
    console.log(sum);       //5

    JavaScript执行代码时,会创建一个上下文执行环境,全局环境是最外围的环境。每个函数在被调用时都会创建自己的执行环境,当函数执行完,当前执行环境被销毁。

    每个执行环境都有一个与之关联的作用域链。在执行代码时,JavaScript引擎会通过搜索执行环境的作用域链来解析变量和函数名这样的标识符。 解析过程从作用域链的前端开始,向上逐级查询与给定名字匹配的标识符,一旦找到标识符,搜索过程就停止,否则继续沿作用域链向上搜索,一直搜索到全局对象。如果没有搜到,则认为该标识符未定义。标识符在作用域链中的位置越深,查找和访问它的时间越长,所以尽可能使用局部变量。

    全局环境只能访问在全局环境中定义的变量和函数,不能直接访问局部环境中的任何数据。

    三.  没有块级作用域

    JavaScript中没有块级作用域,举个例子。如果JavaScript中有块级作用域的话,控制台输出的应该是undefined。但实际上控制台输出的是100,这是为什么呢? 原因在于:没有块级作用域,变量i没有被销毁,因此还能访问到这个变量。

    for(var i=0; i<100; i++) {
        //todo
    }
    console.log(i);   //100

    JavaScript中存在函数作用域。当foo函数执行完毕后,函数内的变量将被销毁,因此控制台报错。

    function foo() {
        var bar = "fn";
    }
    foo();
    console.log(bar);  //报错:ReferenceError: bar is not defined.

    函数作用域模拟块级作用域。

    (function() {
        for(var i=0; i<100; i++) {
            //todo
        }
    })();
    console.log(i);   //报错:ReferenceError: bar is not defined.

    再看一例:局部变量a在整个foo函数内部都有定义的,隐藏了全局变量a。但第一个console在变量初始化之前,所以其值为undefined。

    var a = 8;
    var foo = function() {
        console.log(a);     //undefined
        var a = 5;
        console.log(a);     //5
    };
    foo();


    四. 未赋值的变量和未定义的变量

    未赋值的变量值为undefined,而使用未定义的变量会引起错误。

    var a;
    console.log(a);  //undefined
    console.log(b);  //ReferenceError: b is not defined


    五. 垃圾收集(garbage collection)

    JavaScript具有自动垃圾收集机制,Javascript解释器可以检测到何时程序不再使用一个对象,就把它所占用的内存释放。

    时间:2014-10-22

    地点:合肥

    引用:http://wlog.cn/javascript/javascript-variable-scope-chain.html 

            http://segmentfault.com/blog/liangyi/1190000000692129

  • 相关阅读:
    Linux中find命令用法全汇总,看完就没有不会用的!
    ubuntu16.04 通过命令,修改屏幕分辨率
    Linux下如何查看哪些进程占用的CPU内存资源最多
    shell脚本 在后台执行de 命令 >> 文件 2>&1 将标准输出与错误输出共同写入到文件中(追加到原有内容的后面)
    ef linq 访问视图返回结果重复
    asp.net core web 本地iis开发
    jQuery控制TR显示隐藏
    mvc EF 从数据库更新实体,添加视图实体时添加不上的问题
    无法确定依赖操作的有效顺序。由于外键约束、模型要求或存储生成的值,因此可能存在依赖关系
    还原差异备份——因为没有文件可用于前滚
  • 原文地址:https://www.cnblogs.com/sun-mile-rain/p/4043356.html
Copyright © 2011-2022 走看看