1 作用域
常见的作用域主要分为几个类型:全局作用域、函数作用域、块状作用域、动态作用域。
如果一个 变量 或者其他表达式不在 “当前的作用域”,那么JavaScript机制会继续沿着作用域链上查找直到全局作用域(global或浏览器中的window)如果找不到将不可被使用。 作用域也可以根据代码层次分层,以便子作用域可以访问父作用域,通常是指沿着链式的作用域链查找而不能从父作用域引用子作用域中的变量和引用
2.1 练习1
2.2 全局变量
变量在函数或者代码块{} 外定义,即为全局作用域。不过,在函数或者代码块{} 内未定义的变量也是拥有全局作用域的(不推荐)。
var carName = " Volvo";
// 此处可调用 carName 变量
function myFunction() {
// 函数内可调用 carName 变量
}
上述代码中变量 carName 就是在函数外定义的,它是拥有全局作用域的。这个变量可以在任意地方被读取或者修改,当然如果变量在函数内没有明(没有使用 var 关键字),该变量依然为全局变量。
// 此处可调用 carName 变量
function myFunction() {
carName = "Volvo";
// 此处可调用 carName 变量
}
以上实例中 carName 在函数内,但是拥有全局作用域,它将作为 global 或者 window 的属性存在。
在函数内部或代码块中没有定义的变量实际上是作为 window/global 的属性存在,而不是全局变量。换句话说没有使用 var 定义的变量虽然拥有全局作用域,但是它是可以被 delete 的,而全局变量不可以。
2.3 函数作用域
在函数内部定义的变量,就是局部作用域。函数作用域内,对外是封闭的,从外层的作用域无法直接访问函数内部的作用域
2.4 动态作用域 this
2.5 let
let
声明的变量拥有块级作用域
{
let a = 1
}
console.log(a); //undefined
a 变量是在代码块{} 中使用 let 定义的,它的作用域是这个代码块内部,外部无法访问。
let
声明的全局变量不是全局对象的属性
这就意味着,你不可以通过 window.变量名 的方式访问这些变量,而 var 声明的全局变量是 window 的属性,是可以通过 window.变量名 的方式访
的。
var a = 1
console.log(window.a); //1
let a = 1
console.log(window.a); // undefined
- 用let重定义变量会抛出一个语法错误
这个很容易理解,使用 var 可以重复定义,使用 let 却不可以。
var a = 1
var a = 2
console.log(a) //2
如果是 let ,则会报错
let a = 1
let a = 2
// VM131:1 Uncaught SyntaxError: Identifier 'a' has already been declared
// at <anonymous>:1:1
- let 声明的变量不会进行变量提升
function test () {
console.log(a)
var a = 1
}
test() //undefined
上述代码中, a 的调用在声明之前,所以它的值是 undefined,而不是 Uncaught ReferenceError。实际上因为 var 会导致变量提升,上述代码和的代码等同:
function test () {
var a
console.log(a)
a = 1
}
2.6 const
let
有的特性const
都有- 必须在初始化的时候赋值