坑
1Q:未声明变量,直接输出会出现什么结果?
console.log(num);
1A:报错:变量未被定义。
Uncaught ReferenceError: num is not defined
2Q:在输出变量后才声明并赋值变量会出现什么结果?1
console.log(num);
var num = 10;
2A:显示undefined
。
undefined
3Q:先调用函数,再定义函数会出现什么结果?2
fn();
function fn() {
console.log('Javier_Ji');
}
3A:正常显示。
Javier_Ji
4Q:先调用函数,再声明函数表达式会出现什么结果?3
fn();
var fn = function() {
console.log('Javier_Ji');
}
4A:错误:fn
不是函数。
Uncaught TypeError: fn is not a function
解释
- JavaScript代码是由浏览器中的JavaScript解析器来执行的。JavaScript解析器在运行JavaScript代码的时候分为两步:
- 预解析:js引擎会把js里面的所有的
var
以及function
提升到当前作用域的最前面。 - 代码执行:按照代码书写的顺序从上往下执行。
- 预解析:js引擎会把js里面的所有的
- 预解析分为:变量预解析(变量提升)和函数预解析(函数提升)
- 变量提升:把所有的变量声明提升到当前的作用域最前面,不提升赋值操作。
- 函数提升:把所有的函数声明提升到当前的作用域最前面,不调用函数。
示例
下面的代码执行后会得到什么结果?4
fn();
console.log(c);
console.log(b);
console.log(a);
function fn() {
var a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}
执行后结果如下:
9
9
9
9
9
Uncaught ReferenceError: a is not defined
针对2Q的解答
先预解析,相当于执行了如下代码:
↩︎var num; //把变量声明提升到当前作用域(本例中是全局)最前面 console.log(num); //执行后续的代码 num = 10; //赋值
针对3Q的解答
先预解析,相当于执行了如下代码:
↩︎function() { console.log('Javier_Ji'); } //把函数声明提升到当前作用域(本例中是全局)最前面 fn(); //执行后续的代码,函数被正常调用
针对4Q的解答
先预解析,相当于执行了如下代码:
↩︎var fn; //把var声明提升到当前作用域(本例中是全局)最前面 fn(); //执行后续的代码,由于函数还没被定义,且var fn;语句定义的是变量,则会报错,fn不是函数 function() { console.log('Javier_Ji'); } //执行后续的代码
针对示例的解答
先预解析,相当于执行了如下代码:function fn() { var a; a = b = c = 9; console.log(a); console.log(b); console.log(c); } fn(); console.log(c); console.log(b); console.log(a);
本例中的代码
var a = b = c = 9;
相当于先在函数内部定义变量var a
,之后赋值a = b = c = 9
,由此可得,变量a
的作用域是在fn
函数内部,而b
和c
相当于定义了一个全局变量。 ↩︎