昨天碰到小伙伴在问js函数提升的问题,虽然知道一点,但感觉自己说不清楚,于是搜了一下,找到一篇说的比较明白的翻译,参考地址如下:
http://www.cnblogs.com/betarabbit/archive/2012/01/28/2330446.html
1、理解js的作用域是函数级作用域。
大学学的C语言,块级作用域(block-level scope)早已印刻在我婶婶的脑海里,所以经常写出来这样的代码:
function setPrice(num){
if( num >0 ){
var price = num;
}else{
var price = -num;
}
}
于是webstorem就给我的两个var标红了,那就改改呗,改成了这样:
function setPrice(num){
var price;
if( num >0 ){
price = num;
}else{
price = -num;
}
}
感觉自己好机智,然而这是怎么回事奈?
因为JavaScript是函数级作用域(function-level scope)。
也就是只有函数才会创建新的作用域,函数内的if,else块公用一个function的作用域。
2、说说“变量”提升
叫它们“变量”并不是很合适,目前没有想出来它们的名字,先暂时这样写吧。
在一个函数里可能出现的有下面这几种“变量”:
(1)语言自身定义(Language-defined): 所有的作用域默认都会包含this和arguments。
(2)函数形参(Formal parameters): 函数有名字的形参会进入到函数体的作用域中。
(3)函数声明(Function decalrations): 通过function的形式。
(4)变量声明(Variable declarations): 通过var的形式。(这里需要注意的是,ES6 出现了let这个专门针对块级区域的变量哟~)
以前师傅总让我把函数里的变量的声明写在函数的最上面,一直不明白为什么,也没有想到过,确实函数的声明也应该写在函数的最上面,那么这是为什么奈?
那时因为一个神奇的事情,名叫hoisting(提升),就是说,无论你是函数声明还是变量声明都会在js解释的时候被提升到他们作用域的最顶端。
setPrice: function(orginPrice,discount,coupon){ var price;if(discount){ price = calculateDiscount(orginPrice,discount); }else{ price = calculateCoupon(orginPrice,discount); }function calculateDiscount(price,discount){ return orginPrice * ( 1 - discount); } function calculateCoupon(price,coupon){ return orginPrice - coupon; }this.down(‘#price‘).setData(price);}
这里的calculateDiscount,calculateCoupon的两个方法写在了执行语句的下边,但是并不会影响函数的执行,就是因为函数在解释时被提升的缘故。
需要注意的是声明的赋值部分并没有被提升。
也就是说
function aaa(){
var a = 0 ;
}
这段函数被解释后是
function aaa(){
var a ;
a = 0;
}
恩~差不多久是这个样子啦~