Javascript变量作用域详解

Javascript变量作用域详解

JS作用域划定规矩

  1. JS大部分情况下没有块级作用域, 除非你运用let

  2. 当你运用var的情况下, JS仅仅支撑函数作用域

  3. 不运用var, let声明的变量为全局变量

  4. 不必let情况下, JS中部分变量只能经由过程var和函数参数声明

1. JS大部分情况下没有块级作用域, 除非你运用let

与许多言语差别, JS在ES6之前并没有块级作用域:

function test() { // 一个作用域
    for(var i = 0; i < 10; i++) { // 不是一个作用域
        // count
    }
    console.log(i); // 10
    
    for(let j = 0; j < 10; j++) { // 是一个自力作用域
        // count
    }
    console.log(j); // j is not defined
}

本例中i并不只存在于for轮回的区域中而是存在于全部test函数中. 假如我们用let声明变量i, i则具有了块级作用域

2. 在你运用var的情况下, JS仅仅支撑函数作用域

适才讲了在ES6之前JS没有块级作用域, 那有什么作用域呢? 答案是函数作用域.

function test() {
  var a = 'hello'
}
test()
console.log(a) // a is not defined

本例中在函数内部声明的变量a的作用域仅限于函数内部, 所以在函数外部我们不能访问到.

3. 不运用var, let声明的变量为全局变量

假如我们把上面的例子中的var去掉会发作什么呢?

function test() {
  a = 'hello'
}
test()
console.log(a) // hello

4. 不必let情况下, JS中部分变量只能经由过程var和函数参数声明

由上面的剖析我们晓得, 函数内部声明的变量的作用域为函数内也就是属于部分变量.

//Exp1: 典范错例
for (var i = 0; i < 10; i++){  
    setTimeout(function(){
        console.log(i);
    }, 1000);
} // 10 10 10...

//Exp2: 应用setTimeout函数传入参数
for (var i = 0; i < 10; i++){  
    setTimeout(function(i){
        console.log(i);
    }, 1000, i);
} // 1 2 3 4 ...

//Exp3: 应用bind传入函数参数
for (var i = 0; i < 10; i++){  
    setTimeout(function(i){
        console.log(i);
    }.bind(null, i), 1000);
} // 1 2 3 4 ...

//Exp4: 应用闭包的性子传入参数
var cb = function(i) {
  return function() {
    console.log(i)
  }
}
for (var i = 0; i < 10; i++){  
    setTimeout(cb(i), 1000);
} // 1 2 3 4 ...

后三个例子看似无关联实在道理是一致的: 把变量看成函数参数传入函数, 如许变量就在函数中有了部分作用域而非全局作用域.
固然, 这实际上是JS设想上的缺点, 在ES6时期我们只需要经由过程let建立具有快级作用域的变量就能够轻松处理上述问题了.

//Exp5: 应用let建立块级作用域参数
for (let i = 0; i < 10; i++){  
    setTimeout(function(){
        console.log(i);
    }, 1000);
} // 1 2 3...
    原文作者:ycczkl
    原文地址: https://segmentfault.com/a/1190000007731512
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞