楔子
for(var i=0;i<10;i++){
setTimeout(function(){console.log(i)},100*i)
}
输出
10
10
10
10
10
10
10
10
10
10
然而我们期望的输出是
0
1
2
3
4
5
6
7
8
9
修改一下上面的代码 IIFE
for(var i=0;i<10;i++){
(function(i){
setTimeout(function(){console.log(i)},100*i)
})(i)
}
或者 使用 let 声明变量
for(let i=0;i<10;i++){
setTimeout(function(){console.log(i)},100*i)
}
执行可以如我们所期望的一样输出结果
在ES6之前的JavaScript没有块级作用域,{}中使用var定义的变量,在{}之外也可以访问。如
if(true){
var i = 1;
}
console.log(i) // 1
使用let声明的变量,它使用的是块作用域
{
let i = 0;
}
console.log(i)
Uncaught ReferenceError: i is not defined
定义在函数中的变量是函数作用域,函数的参数也是函数作用域
function foo(){
var i = 1;
console.log(i)
}
foo();
console.log(i)
Uncaught ReferenceError: i is not defined
var a = 2;
function koo(a){
a = 1;
}
koo(a)
console.log(a)
2
var obj = {a:2};
function goo(a){
a = 1;
}
goo(obj)
console.log(obj)
{a:2}
变量提升
var i = 1;
function foo(){
console.log(i);
var i = 2;
}
foo()
执行
undefined
相当于
var i = 1;
function foo(){
var i;
console.log(i);
i = 2;
}
函数提升
函数表达式
foo();
function foo(){
console.log(`foo`)
}
执行
foo
函数声明
foo();
var foo = function(){
console.log(`foo`)
}
执行
Uncaught TypeError: foo is not a function
全局作用域
var i = 1;
function foo(){
console.log(i)
}
foo()
1
全局变量的作用域是全局作用域,在任何地方都可以访问,应避免声明全局变量
作用域链
var a = 1;
function foo(){
var b = 1;
return function(){
var c = 1;
var r = a + b + c;
return r;
}
}
var koo = foo();
koo()
3