JS声明提升

Because variable declarations (and declarations in general) are processed before any code is executed, declaring a variable anywhere in the code is equivalent to declaring it at the top. This also means that a variable can appear to be used before it’s declared. This behavior is called “hoisting”, as it appears that the variable declaration is moved to the top of the function or global code.———–MDN-var_hoisting

变量提升

直觉上总是认为javascript代码是自上而下执行,这在其它语言中总是如此:

printf("%d\n",a);//compile error,a is not define
int a = 10;

但是,这在javascript中并不完全正确。我们知道,利用var声明的变量,会被添加到当前作用域的变量对象中去。即任何声明在某个作用域内的变量,都将属于这个作用域。但是,变量声明出现的位置与作用域之间的关系,与其它语言存在些许差别,考虑如下代码:

console.log(a);//Uncaught ReferenceError: a is not defined.
console.log(a);//undefined
var a = 20;

第一段代码很显然,由于a未被声明,报出异常;
第二段代码,输出undefined,这是由于在javascript引擎解释执行代码之前,会先进行编译,编译的工作中就包括找出所有的标识符声明,并将其与各自的作用域相对应起来,这里的声明包括变量和函数。即所有的变量和函数的声明都会在任何代码执行之前先被处理,这个处理的过程称之为“提升”。第二段代码其实会按照如下的处理方式进行处理:

var a;
console.log(a);
a = 20;

即声明被提升到作用域的前端了。提升都是对于作用域来说的,无论是全局作用域中还是函数作用域中:

funtion foo(){
    console.log(a);//undefined
    var a = 20;
}

函数提升

要理解函数提升,首先要清楚两个概念,函数声明和函数表达式。javascript中定义函数有两种常用的方式:

function foo(){
    statement...
}
var foo = function(){
    statement...
}
/* 函数表达式,但是在safari中会报错 */
var fun = function fun(){
    statement...
}

前一种是函数声明的方式,后一种是函数表达式的方式。其实要区分二者,很简单,考察关键字function出现在整个声明中的位置,如果function是整个声明的第一个词,那么就是函数声明。如下:

(function foo(){console.log(1);});//即使是被括号包裹,foo就成了一个函数表达式

javascript引擎会对函数声明进行提升,而函数表达式并不会,考虑如下代码:

foo();//1
function foo(){
    console.log(1);
}
foo();//Uncaught TypeError:foo is not a function
var foo = function(){
    console.log(2);
}

由于函数表达式不会被提升,但是变量声明会被提升,所以上述第二段代码的实际效果是:

var foo;//声明,默认初始化为undefined
foo();//Uncaught TypeError:foo is not a function
foo = function(){
    console.log(2);
}

如果同时存在函数声明提升和变量提升,结果会怎么样呢?javascript引擎会首先进行函数声明提升,其次才是变量:

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

上述代码能够正确输出1,是因为函数声明首先被提升到当前作用域的前端,之后,编译器发现foo已经声明,后面的重复声明会被忽略(与其它语言不同,javascript允许重复声明,只是编译器遇到重复声明会忽略),即上述代码的实际效果是:

function foo(){
    console.log(1);
}
foo();
foo = 20;
foo = function(){
    console.log(2);
}

要记住,提升的只是声明,而赋值或者其它的执行均会保留在原地不会被提升

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值