Let & Const
全局作用域
函数作用域
块状作用域
动态作用域
全局作用域
函数外部定义的遍历,基本都是全局作用域
全局作用域的变量可以在文件任何位置访问到
在a.js中定义 var first = ‘123’, 新建b.js,在b.js中还可以访问到first
var定义的全局变量,是window的属性
不加var、let、const定义的变量,不是全局变量,是window的属性
second = '1345'
second没有使用var,拥有全局作用域,但不是全局变量。
变量不可以被删除,属性可以被删除。
delete first //false
delete second //true
delete window.second//true
second作为window的属性存在。
函数内部不使用var定义的变量,也是window的属性,具有全局作用域。
函数作用域
在函数内部使用var定义的变量
函数作用域链
function test (){
var a = 3
function test2() {
var b = 4
return a + b + c//a向上找,为3,c向上找,看是否有window.c,没有则返回undefined
}
return test2
}
块状作用域
变量提升
function test (){
var a = 3
if(a === 3) {
var b = 4
}
}
//浏览器会理解为
function test (){
var a = 3
var b
if(a === 3) {
b = 4
}
}
用let
function test (){
var a = 3
if(a === 3) {
let b = 4
}
console.log(b)//undefined
}
动态作用域
window.a = 3
function test() {
console.log(this.a)
}
test()//3
//改一下代码
window.a = 3
function test() {
console.log(this.a)
}
test()//100
test.bind({a:100})()
this不固定指向window
let与const
let声明的变量有块状作用域
var b = 3
let c = 4
console.log(b,c)//3 4
console.log(window.b, window.c)//3 undefined
var b = 4//可,eslint会报错,但是console.log(b) //4
let c = 5 //不行,let不能重复定义
let定义的变量
- 有块状作用域
- 不会是window的属性
- 不会变量提升
- 不能重复定义
const 有let的四个特性,并且const定义的变量不能修改值
阅读:
什么是作用域
Javascript深入之词法作用域和动态作用域
深入理解JS中声明提升、作用域(链)和this关键字
题目
1.请问下面代码输出是什么?如何能根据i的顺序输出?
for(var i = 0;i< 3;i++){
setTimeout(function () {
console.log(i);
},1000)
}
//输出三个3
2. 发生什么?
console.log(a)
let a = 1;
//ReferenceError: Cannot access 'a' before initialization
//因为let没有变量提升
//如果是var
console.log(a)//undefined
var a = 1;
//浏览器理解为
var a
console.log(a)
a = 1;