Javascript变量与函数的声明与提升

简单介绍编译与变量、函数声明的关系。

  • Javasript编译分两个阶段:
    1. 预编译阶段
      • 将代码中的变量声明与声明式函数提前(预编译)
    2. 编译阶段
      • 此时变量的赋值、函数执行等操作才会进行

变量的声明

console.log(a); // undefined
var a = 1;
console.log(a); // 1

上面的代码我们可以这样看:

var a;          // 变量a的声明被提升(预编译)
console.log(a); // undefined
a = 1;          // 变量a被赋值为1
console.log(a); // 1

注意:从上面的代码我们可以看到变量的声明部分提升,赋值部分并不会被提升。


函数的声明

声明函数会被提前

foo();  // 2
function foo () {
    console.log(2);
}
foo();  // 2

上面的代码我们可以这样看:

function foo () {
    console.log(2);
}
foo();  // 2
foo();  // 2

函数表达式不会被提前

bar();  // TypeError: bar is not a function
var bar = function foo () {
    console.log(3)
}
// foo();   // ReferenceError: foo is not defined

注意:我们尝试在函数表达式之后执行 foo(),结果抛出 ReferenceError: foo is not defined,当前作用域下找不到 foo,但是在 foo函数内部可以执行,也就是自己调用自己,注意会陷入死循环。

函数局部变量提升

局部变量在局部提升,外部访问不到。

foo();
function foo () {
    console.log(a);    // undefined
    var a = 1;
    console.log(a);    // 1
}

声明同名函数

函数声明会被提前,同名函数后者会覆盖前者;
函数表达式不会被提前,同名变量声明 var foo; 提升会被忽略;
就是多个同名的变量声明,只会提升一次。

foo();  // 3
function foo () {
    console.log(1);
}
var foo = function foo () {
    console.log(2);
}
function foo () {
    console.log(3);
}
foo(); // 2

if else for等创建代码块的语句,内部声明函数

foo();
if (true) {
    function foo () { 
        console.log(1);
    }
} else {
    function foo() {
        console.log(2);
    }
}

代码块内部函数声明是否提前不同浏览器表现不一致, IE9及以下(更高版本没试过) => 输出 2,
函数处于 if else 代码块中,预编译阶段将其全部提前,即使 else 部分不会执行。
高级浏览器(Chrome、Firefox) => 抛出 TypeError: foo is not a function
只将函数名提升,函数体并未提升。

我们将函数执行的放到if 代码块中

if (true) {
    foo();
    function foo () { 
        console.log(1);
    }
} else {
    function foo() {
        console.log(2);
    }
}

IE9以下浏览器表示一致; 高级浏览器 => 输出 1 。
低版本浏览器中,预编译阶段即使处于 if else 、for 等创建代码块的语句,会将函数声明提前。
而高级浏览器中,只会提前函数名,只有当执行到相应代码块时,才会将全部提前。

函数内部的变量、函数声明与参数

foo(1);
function foo (a) {
    console.log(a);    // function a () {// ...}
    var a= 2;
    function a() {
        // ...
    }
    console.log(a);    // 2
}

简述执行顺序:

1.预编译阶段,foo函数声明被提前;
3.执行并传参foo(1),形参 var a = 1;
4.函数内部预编译,a函数声明被提前,var a 变量提前被忽略。
5.输出a => function a () {// …}
6.赋值a = 2;
7.输出a => 2


个人学习总结,如有不足欢迎指正。

参考博客JavaScript提升(你不知道的JavaScript)


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值