var arr = [];
for (let i = 0; i < 2; i++) {
arr[i] = function () {
console.log(i);
}
}
arr[0](); // 使用var,则输出2;使用let则输出0
arr[1](); // 使用var,则输出2;使用let则输出0
console.log(window.arr[0]);
// 在全局作用域能够被调用的函数,都属于全局函数,都属于window的方法
// 函数首先查找全局作用域下的值,然后查找本身所在的作用域下的值
console.log('--------------');
let a;
function fn1() {
var j = 1;
console.log(j);
a = function fn2() { // 将此处的fn2删除,使其成为匿名函数,函数外部仍然不能通过a()调用fn2
console.log(j + 1);
}
}
fn1(); // 输出1
// fn2(); 报错,因为属于局部函数,不能在全局作用域调用
// console.log(window.fn2()); 报错
console.log(window.fn2); // undefined
// a(); 使用let或var声明a,此处会报错,因为a是函数内部的局部变量
console.log(a()); // undefined 在外部使用let声明a,再给它赋值函数,仍然无法调用fn2
console.log('--------------');
for (var i = 0; i < 3; i++) {
//△ let a = function () {
//△ console.log(i);
//△ }
arr[0](); // 如果for循环里面使用let,只输出一次2;如果for循环里面用var,输出三次,0\1\2
// 如果使用var ,相当于每次循环都更新全局变量i,一共创建了四个变量i:0,1,2,3,此时function取到的值为全局变量i,每个迭代中取到的值不同
// 如果使用let,let创建的变量i与该for循环块级作用域绑定,与其他地方无关,function在该块级作用域外部,不可能取到此时let创建的任意一个i
// 如果把前一个循环的变量声明改成let,此处输出三次0。因为此时arr[0]函数使用的i是前一个循环里面let声明的和该作用域绑定的i,不会受这个for循环里面声明的全局变量i影响。同样此时把这个for循环里面改成let声明变量,也会输出三次0,因为两个i都被绑定在各自的块级作用域下,不会互相干扰
}
//△ console.log(a()); 报错
console.log(i); // 3