持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第15天,点击查看活动详情
前言
今天没有写博客没有什么思路,于是决定去刷下js题目,做一个题目解析.
错题如下:
选项如下:
1.错误思路
- (1)分析结构:
- 一共三行代码
- 第一行声明一个变量
- 第二行声明一个函数
- 第三行调用前面声明的函数
- (2)分析考官意图,题目考察点
- 考察对作用域的理解
- 全局作用域全局有效,局部作用域函数内有效,块级作用域,块内有效
- 考察变量的查找顺序
- 先在本作用域内查找,查找不到则到上一级作用域内查找
- (3)得出答案
test()会输出a的值- 本题中有,两个地方有a的值
- 一个是全局作用域,一个是块级作用域
console.log(a)在函数的局部作用域中,无法向下查找到块级作用域中的a=2- 可以向上查找到全局作用域中的
var a=1 - 所以
console.log(a)的值为1 - 选A:1
2.本题正确思路
- (1)分析结构:
- 一共三行代码
- 第一行声明一个变量
- 第二行声明一个函数
- 第三行调用前面声明的函数
- (2)分析考官意图,题目考察点
- 考察对作用域的理解
- 全局作用域全局有效,局部作用域函数内有效,块级作用域,块内有效
- 考察变量的查找顺序,作用域链
- 局部内能找到就用局部的找不到采取用外面的
- 现在本作用域内查找,查找不到则到上一级作用域内查找
- (3)得出答案
test()会输出a的值- 本题中有,两个地方有a的值
- 一个是全局作用域,一个是块级作用域
console.log(a)在函数的局部作用域中,本来无法向下查找到块级作用域中的a=2- 但是var会变量提升,本质上只分全局和局部,所以
var a = 2是局部变量 - 作用域链先查找当前作用域所以会查找到
var a = 2 - 由于var会变量提升,
console.log(a)时a声明了,没有赋值 - 并且if(false)所以
a = 2永远不会赋值 - 所以
console.log(a)的值为undefined - 选C:undefined
3.实际调试一下
<script>
var a = 1;
function test() {
console.log(a);
if (false) {
var a = 2;
}
}
test();
</script>
输出为undefined
如果var换成let会怎样?
<script>
let a = 1;
function test() {
console.log(a);
if (false) {
let a = 2;
}
}
test();
</script>
- 此时
console.log(a)只会访问到全局变量,不会访问到块级变量 - let 相比var 有严格的作用域限制
4.反思总结
作用域链
一般情况下,变量到创建这个变量作用域中取值。
但是如果在当前作用域中没有查到值,就会向上级作用域去查,直到查到全局作用域,这么一个查找过程形成的链条就叫做作用域链。
- 在函数内找不到a,就到全局作用域上找
var的变量提升
var的变量提升特性,只是提前声明这一步,赋值这一步明没有提前
console.log(a)
var a = 1
//undefined
这是因为var的变量提升特性,使得上面的代码转化为下面写的
var a
console.log(a)
a = 1
//undefined