js作用域有哪些?

ES6之前的JS是不存在“块级作用域”的,例如:

if(true) {
  var name = 'andy'
}
console.log(name)  // andy

作用域,通俗来讲就是一个独立的地盘,让变量不会外泄、暴露出去。

上面例子中name就被暴露出去了,所以说,JS没有块级作用域,只有全局作用域和函数作用域。

var a = 100
function fn() {
  var a = 200
  console.log('fn', a)
}
console.log('global', a)
fn()

// global 100
// fn 200

全局作用域就是最外层的作用域,如果我们写了很多行js代码,所有的变量定义都没有用函数包括,那么它们全都在全局作用域中。这样的坏处是:变量之间很容易撞车、冲突。

// 小明写的代码
var data = {a: 100}

// 小红写的代码
var data = {x: true}

我们可以观察下jQuery、Zepto等库的源码,所有的代码都会放在(function(){…})()中。因为放在里面的所有变量,都不会被外泄和暴露,不会污染到外面,不会对其他的库或JS脚本造成影响。这就是函数作用域的一个体现。

jQuery

ES6加入了“块级作用域”,我们使用let定义变量即可,如下:

if(true) {
  let name = 'andy'
}
console.log(name) // 报错,因为let定义的name是在if这个块级作用域