美文网首页Javascript教程
Javascript教程(八)变量作用域

Javascript教程(八)变量作用域

作者: klmhly | 来源:发表于2018-05-23 10:14 被阅读0次

    Javascript用关键字 var 声明的变量有函数作用域全局作用域两种
    Javascript用关键字 let 声明的变量有块级作用域
    var声明的变量有变量提升,let没有变量提升

    1. var-函数作用域
    1.1 如果一个变量在函数体内部申明,则该变量的作用域为整个函数体,在函数体外不可引用该变量

    function foo() {
        var x = 1;
        x = x + 1;
    }
    
    x = x + 2; // ReferenceError! 无法在函数体外引用变量x
    

    1.2 不同函数内部的同名变量互相独立,互不影响.

    function foo() {                
        var x = 1;                      //仅在这个函数体内有作用
        x = x + 1;
    }                          
    
    function bar() {
        var x = 'A';                     //仅在这个函数体内有作用
        x = x + 'B';
    }
    

    1.3 对于嵌套函数内部函数可以访问外部函数定义的变量,外部函数不能访问内部函数的变量。

    function foo() {
        var x = 1;      //外部函数的变量 x
        function bar() {
            var y = x + 1; // bar可以访问foo的变量x!
        }
        var z = y + 1; // ReferenceError! foo不可以访问bar的变量y!
    }
    
    function foo() {
        var x = 1;
        function bar() {
            var x = 'A';
            console.log('x in bar() = ' + x); // 'A'
        }
        console.log('x in foo() = ' + x); // 1
        bar();
    }
    foo();                   //x in foo() = 1          x in bar() = A
    

    说明:JavaScript的函数在查找变量时从自身函数定义开始从“内”向“外”查找。如果内部函数定义了与外部函数重名的变量,则内部函数的变量将“屏蔽”外部函数的变量

    1.4 变量提升
    JavaScript的函数定义有个特点,它会先扫描整个函数体的语句,把所有申明的变量“提升”到函数顶部

    function foo() {
        var x = 'Hello, ' + y;                     
        console.log(x);                                //输出  hello  undefined
        var y = 'Bob';
    }
    foo();
    

    实际上,JavaScript引擎看到的代码相当于

    function foo() {
        var y; // 提升变量y的申明,此时y为undefined
        var x = 'Hello, ' + y;
        console.log(x);
        y = 'Bob';
    }
    

    由于JavaScript的这一怪异的“特性”,我们在函数内部定义变量时,请严格遵守在函数内部首先申明所有变量这一规则

    2. var-全局作用域
    不在任何函数内定义的变量就具有全局作用域

        var funcs = []
        for (var i = 0; i < 10; i++) {         //这里在for循环里定义的 var i 是全局作用域
            funcs.push(function() { console.log(i) })
        }
    
        funcs.forEach(function(func) {
            func()                                  //结果是输出10 十次。
        })
    

    分析:每次for循环数组里面加一个函数.执行完循环,i=10,并且最后funcs数组里面放了10个函数。
    funcs.forEach数组调用这个方法,回调函数的参数func就是数组里面的每个元素,对数组里面的每个元素执行func() ,相当于执行数组元素的函数体console.log(i) ,所以所有的执行都是输出10

    3. let块级作用域
    ES6引入了新的关键字let,用let替代var可以申明一个块级作用域的变量

    function foo() {
        var sum = 0;
        for (let i=0; i<100; i++) {
            sum += i;
        }
       
        i += 1;    // SyntaxError:仅在for循环体内有作用
    }
    

    对比全局作用域的例子

    const funcs = []
        for (let i = 0; i < 10; i++) {
            funcs.push(function() {
                console.log(i)
            })
        }
        funcs.forEach(func => func())          //输出0,1,2,3,4,5,6,7,8,9
    

    相关文章

      网友评论

        本文标题:Javascript教程(八)变量作用域

        本文链接:https://www.haomeiwen.com/subject/rziljftx.html