- 作用域相关题目一
var funcs = []
for (var i = 0; i < 10; i++) {
funcs.push(function() {
return i;
})
console.log(funcs[i]())
}
funcs.forEach(function(func) {
console.log(func());
})复制代码
这道题的输出结果
解析:funcs数组Push进去了十个匿名函数,在for循环的作用域内直接调用可以输出i的值,在for循环结束后,全局变量i 的值为10,此时forEach函数遍历调用里面的匿名函数,沿着作用域向上寻找到 i =10,所以打印十个10
这题还涉及到一个关键的知识:函数只有在调用的时候才会执行内部的方法,否则只是定义了一个方法
如何让forEach正确输出0-9,有两种方法
方法1:ES5的立即执行函数
立即执行函数会创建一个独立的作用域,相当于“私有”的命名空间
var funcs = []
for(var i = 0; i < 10; i++) {
funcs.push(
(function(value) {
return function() {
return value;
}
})(i)
)
}
funcs.forEach(function(func) {
console.log(func())
})
复制代码
方法2:ES6的let
var funcs = []
for (let i = 0; i < 10; i++) {
funcs.push(function() {
return i;
})
console.log(funcs[i]())
}
funcs.forEach(function(func) {
console.log(func());
})复制代码
2.题目二
console.log(a) // undefined
var a = 100
console.log(a) // 100
function person(name){ // 声明函数
age=20
console.log(name,age)
var age
}
person('man') // double,20复制代码
浏览器解析时,把变量进行提升,然后全设置为undefined,等到执行到赋值时才进行赋值
3.题目二
var i = 10
function aaa () {
i = 20
console.log(i) // 第1个log 20
for (var i = 0; i < 6; i++) {
console.log(i) // 第2个log 0 1 2 3 4 5
}
console.log(this.i) // 第3个log 10
console.log(i) // 第4个log 6
}
aaa()
console.log(i) // 第5个log 10复制代码
这题涉及到四个点
- 内部环境可以通过作用域链访问所有的外部环境
- 外部环境不能访问内部环境中的任何变量
- 即每个环境都可以向上搜索作用域链,以查询变量和函数
- 任何环境不能向下搜索作用域链而进入另一环境
上面代码等价于下
var i = 10
function aaa () {
var i //变量提升
i = 20
console.log(i) // 第1个log 20
for (i = 0; i < 6; i++) {
console.log(i) // 第2个log 0 1 2 3 4 5
}
console.log(this.i) // 第3个log 10
console.log(i) // 第4个log 6
}
aaa()
console.log(i) // 第5个log 10复制代码
第一个输出 由于给局部变量i赋值 所以输出20
第二个输出for循环 输出0 1 2 3 4 5,当i = 6时终止循环
第三个输出,在一般函数中使用this指代全局对象,此是this.i = window.i 输出10
第四个输出,上面for循环结束后i =6 ,所以输出6
第五个输出,输出全局变量 i =10