js中变量的提升和函数声明提升也是笔试常常会考到的知识点。
1。变量提升
那什么是变量的提升?可以理解为就是不管变量的位置在哪里,它们的声明都会在后台提升至代码顶部。来看看一个例子。
在JS中,就是把定义在后面的(变量或函数)提升到前面中定义。
var world = "Hello World!";
function hello(){
alert(world); //Hello World
}
显然这个结果是显而易见的。如果是这样的话:
var world = "Hello World!";
function hello(){
alert(world); //undefined
var world = "What's Your Name? ";
}
为什么会输出undefined,因为不管变量的位置在哪里,它们的声明都会在后台提升至代码顶部。所以其实上面的代码是这样的。
var world = “Hello World!”;
function hello(){
var world;
alert(world); //undefined
world = “What’s Your Name? “;
}
我们会对world 为什么会弹出出 undefined 有更好的理解了。正如我们所学到的,当局部变量world声明后,它会自动被浏览器提升至函数作用域的顶部,在alert 的时候,变量早已经声明完成,然而,因为变量的初始化不会被提升的,所以变量的值是undefined 。
2。 函数声明提升
定义函数有两种方式:函数声明和函数表达式
函数声明提升会在编译阶段把声明和函数体整体都提前到执行环境顶部,所以我们可以在函数声明之前调用这个函数
函数声明方式提升【成功】
代码如下:
function myTest(){
foo();
function foo(){
alert("我来自 foo");
}
}
myTest();
函数表达式,其实就是变量声明的一种,声明操作会被提升到执行环境顶部,并赋值undefined。赋值操作被留在原地等到执行。
函数表达式方式提升【失败】
代码如下:
function myTest(){
foo();
var foo =function foo(){
alert("我来自 foo");
}
}
myTest();
奇怪的函数声明
复制代码
console.log(a); //undefined
if (false) {
function a() {
console.log(100);
}
}
a();//TypeError: a is not a function 理论上应该是100
奇怪吧??函数提升发生在所有代码执行之前,所以尽管a函数的定义过程写在了if分支中,但是理论上,它是不会影响函数声明提升的
在新版本的浏览器中会出现此问题,旧版本的浏览器中会在控制台中打印出100
这也提醒了我们尽量不要在控制语句中进行声明,会造成很多无法预知的bug
3.函数优先
提升操作会优先进行函数的声明
函数会首先被提升然后才是变量,重复的变量声明会被忽略,只剩下赋值操作,多个函数声明可以进行覆盖
声明的顺序是这样的:
找到所有的函数声明,初始化函数体,如有同名的函数则会进行覆盖
查找变量声明,初始化为undefined,如果已经存在同名的变量,就什么也不做直接略过.
// 1,进行了函数覆盖
foo(); //200
function foo() {
console.log(100);
}
function foo() {
console.log(200);
}
// 2,先初始化了函数foo,后又发现同名的foo,就会什么也不做,即变量foo就会被不理睬
console.log(foo); //function foo(){...}
function foo(){
console.log(200);
}
var foo = 100;