这里的提升,我的理解是包括变量和函数在内的所有声明的提升
而根据对作用域的理解,任何声明在某个作用域内的变量,都将附属于这个作用域。
考虑以下代码
1 | //代码块一 |
上述两段代码的结果是啥?
思考思路:包括变量和函数在内的所有声明都会在任何代码被执行前首先被处理。
变量声明
于是, 上述代码块一,会以如下形式处理:
1 | var a; |
代码块二处理:
1 | var a; |
函数声明
1 | foo(); |
上述代码理解为下面的形式:
1 | function foo() { |
提示:函数声明会被提升,但是函数表达式却不会被提升
如下代码:
1 | foo(); |
可以理解为下面形式:
1 | var foo; |
再来一道题,大家自行理解
1 | foo(); |
提升:变量和函数声明从它们在代码中出现的位置被“移动”到了最上面的过程
重要提示:只有声明本身会被提升,而赋值或其他运行逻辑会留在原地。
函数优先
函数声明和变量声明在被提升的同时,如果在一个作用域中同时存在多个“重复”或者说同名的声明代码中,函数会首先被提升,然后才是变量。
考虑以下代码:
1 | foo(); // 1 |
可以理解为如下形式:
1 | function foo() { |
提示:出现在后面的函数声明还是可以覆盖前面的
js 语言精粹提到的糟粕中有类似的这么一段:
1 | foo(); // 是‘b’ 还是 TypeError: foo is not a function? |
上面这段代码在 Gecko 引擎中打印”TypeError”;而在其他浏览器中则打印”b”。
原因在于 Gecko 加入了 ECMAScript 以外的一个 feature:条件式函数声明。
注意引用的 Note:条件式函数声明跟函数表达式的处理方式一样。因此,条件式函数声明丧失了函数声明提升的特性。
基于以上原因,请不要在你的代码里将函数声明嵌套在条件语句内。
写成函数表达式好了。