作为世界上最优美的语言javascript的使用者,呵呵,js的魅力是无穷的,今天来聊聊他的魅(dan)力(teng)之一,变量提升。
每种语言所定义的变量基本都会有一定得作用域,而js的作用域则存在着一定的陷阱。首先看一下下面一道题:
<script> var str1 = "haha"; var str2 = "hehe"; function t1() { console.log(str1); console.log(str2); var str2 = "kidding"; console.log(str2); } t1(); </script> 结果是: haha undefine kidding
纳尼?hehe哪去了?结果不应该是:haha hehe kidding吗?
实际上这里就有一个变量提升的问题。如果函数写成这样,你可能就一目了然了
<script> var str1 = "haha"; var str2 = "hehe"; function t1() {
var str2;
console.log(str1);
console.log(str2);
str2 = "kidding";
console.log(str2);
}
t1();
</script>
实际上js在解析的时候正是按照这样的执行顺序进行的,在执行到t1内部的时候,会优先找到函数内部作用域里的变量执行,而且函数内的所有var 声明function声明都会被提到函数体的最上方执行。并且var 声明会先声明之后,执行到赋值的时候再赋值。
再看下面的例子:
<script> function t(userName) { console.log(userName); function userName() { console.log('tom'); } } t('toby'); </script>
由于function声明会被提前到函数体最上方,所以相当于这样:
function t(userName) { function userName() { console.log('tom'); } console.log(userName); } t('toby');
结果很明显是:
function userName(){
console.log('tom');
}
但是像下面这样的函数表达式,则会把var t2进行提升,而后再对t2进行赋值
<script>
test();
var test = function () { console.log('hello toby');//这里会输出什么? };
</script>
解析后变成:
<script>
var test ;
test();
test = function () { console.log('hello toby');//这里会输出什么? };
</script>
由于执行到test()的时候,test还是一个undefine所以代码会报错。
但是变量提升只是在该变量在改作用域内从未出现的时候才会发生。看下面的题:
<script> function t(userName) { console.log(userName);// (1) var userName = function () { console.log(userName);//(2) } userName();//(3) } t('haha'); </script>
如果按照刚才所说的变量提升,可能会认为结果是:
(1) 处为undefine
(2)处是
function () {
console.log(userName);//(2)
}
实际上结果是:(1)处输出的是haha ,原因在于执行到t函数内部的时候,userName这个变量在传参的时候在这个内部作用于内已经存在了,所以不会进行变量提升,而是直接使用已经
存在的userName='haha'。(2)执行(3)的时候userName就是一个function了,所以(2)处的结果就一目了然了。
自己的一番拙见,如有不对,还望指出。
参考链接:http://www.jianshu.com/p/43bf4f2e0d57?from=singlemessage