js变量提升小记

  作为世界上最优美的语言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

posted @   断劫断念  阅读(414)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示