博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JS难点之hoist
阅读量:6885 次
发布时间:2019-06-27

本文共 1896 字,大约阅读时间需要 6 分钟。

这篇博文是之前在CSDN写的,现在移至sf。

有过C或者Java类编程经验的同学,对于“先声明后使用”的规则很熟悉,如果使用未声明的变量或者函数,编译时程序会报错!但是,JavaScript却是一个‘大奇葩’,可以在变量或者函数声明之前使用,现在根据我的理解在做一下说明。

首先说明JS的hoist分为变量hoist函数hoist两种。

一、变量hoist

看一段程序

       var a=10;         function fun(){           console.log(a);           var a=100;           console.log(a);        }         fun();//undefined   100         console.log(a);//10  

 

我们知道在js中,作用域分为全局作用域和函数作用域两种(ES6新特性,增加了块级作用域,另做说明)。全局变量声明有三种方式:

  • var(关键字)+变量名(标识符)方式在function外部声明,显示声明
  • 没有使用var,直接给标识符赋值,隐式声明
  • 使用window全局对象来声明,全局对象的属性也应是全局变量 eg:window.test=50; alert(test);

  

好,很显然,var a=10;在程序中是全局变量。那么,按照我们正常的逻辑输出结果为:10  100  10。但是,实际输出结果为:undefined 100  10,其实是JS解析器的解析原因,它会将当前作用域中声明的所有变量和函数,放在作用域的最开始处。但是变量只有其声明被提前在作用域的最开始处,赋值结果仍然还在原来位置。上述代码对于解析器来说,其实是:

       var a=10;         function fun(){          var a;            console.log(a);            a=100;            console.log(a);         }         fun();//undefined   100         console.log(a);//10

二、函数hoist

 

讲完变量hoist,现在再讲一下函数hoist,函数hoist又分为两种情况。一种是函数声明,另一种是函数作为值赋值给变量

先说第一种情况:

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

在这种情况下,可以看出,函数JS解释器允许在函数声明之前使用函数,其实也就说明,在这种情况,不仅函数名提前了,同时,函数体也被提前。所以可以上述代码可以执行。再说第二种情况:

     fun();       var fun=function(){          console.log(2);       }

结果为:Uncaught TypeError: fun is not a function  可以看出在此例中,函数只是变量声明声明提前,但是赋值没有提前,并且被提前的变量默认为undefined,所以报的错误类型为“typeerror”,因为undefined不是函数,不能被调用。

三、变量名和函数名相同时的hoist

       function fun(){console.log(1);}         fun();//2         function fun(){console.log(2);}         fun();//2         var fun=100;         console.log(fun);//100         fun();//报错

在此例中,函数名和变量名相同,都是fun,都会提前,那么在提前时,有什么需要注意的地方呢? 

  • 函数声明比变量声明更置顶
  • 声明过得变量不会重复声明

  

所以上述代码等效于:

function fun(){console.log(1);}       function fun(){console.log(2);}//函数体覆盖上一层函数体       var fun;//实际无效       fun();       fun();       fun=100;       console.log(fun);       fun();

以上就是本人对于JS的hoist问题的理解,如果哪位同学,发现其中有误,欢迎指正!我的微信号为:Alfred-kai。 

转载地址:http://ehxbl.baihongyu.com/

你可能感兴趣的文章
HBase分布式安装手册 - ivaneeo's blog - BlogJava
查看>>
SPOJ 4487 Can you answer these queries VI
查看>>
条款16:成对使用new和delete时要采用相同的形式
查看>>
qt的资源替换搜索QDir具体解释
查看>>
深入研究Java类载入机制
查看>>
String.format() 格式化字符串
查看>>
sqlserver 修改替换text,ntext类型字段的两种方案
查看>>
Java爬虫,信息抓取的实现(转)
查看>>
配置Jenkins使用Gitlab的代码库进行构建
查看>>
rem
查看>>
30Mybatis_mybatis和spring整合-原始dao开发
查看>>
求逆序对数总结 & 归并排序
查看>>
【转载】公钥、私钥、数字签名等知识
查看>>
正则表达式之字符串验证
查看>>
【番外篇】ASP.NET MVC快速入门之免费jQuery控件库(MVC5+EF6)
查看>>
chrome手动添加拓展
查看>>
xUtils怎样通过注解对FindViewById进行封装
查看>>
工作环境换成Ubuntu18.04小记
查看>>
Windows线程的多任务处理
查看>>
C++ 枚举类型的思考
查看>>