You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
foo();// TypeError "foo is not a function"bar();// validbaz();// TypeError "baz is not a function"spam();// ReferenceError "spam is not defined"//匿名函数表达式,foo会被hoistedvarfoo=function(){};//函数申明,bar和函数体都会被hoistedfunctionbar(){};//函数表达式,只有baz会被hoisted,spam就当没看见,因为解析器解析时会忽略这个无用变量varbaz=functionspam(){};foo();// validbar();// validbaz();// validspam();// ReferenceError "spam is not defined"
JavaScript中,函数OR变量提前(Hoist)是什么意思?它在Js中发挥着什么作用呢?本文结合自身经验来解释下这个概念。
其实要说这个概念,需要用到很多JS的概念,如果本文中未讲解的,建议大家先弄懂这些概念。
一、定义
Hoist,[跟我读:好意思特],升起、吊起的意思。
在JS中的解释是:在作用域(Scope)内变量或者函数会提前到作用域顶部执行。
示例:
示例解释:
step 1
,在全局作用域(Global)范围内,定义变量并初始化,再alert,正常显示。step 2
,在()
的包含的匿名函数的作用域内,alert变量myvar,由于当前作用域未定义变量myvar,于是js解析器,会沿着原型链([ScopeType])继续向其指向的父类的原型函数(Prototype)寻找,而父类是window,其中定义的所有变量默认都在其原型函数上,找到了,于是正常显示。step 3
,这里使用到了JS的另一个概念(变量提前),下文解释这个问题。扩展阅读:
二、求解
我们通过
Hoist
的定义可以知道,在作用域范围内,变量和函数提前执行,那么上题可以变形为:而我们知道JS在当前作用域内是自上而下顺序执行的。所以,当执行到alert的时候,myvar还未初始化,所以结果就是undefined。
这里其实有2个隐身概念,即:
本节就说到这里,下节继续烧脑。
三、探秘
首先针对上节遗留2个问题,进行回答。
3.1 JS对函数解析执行的顺序
记忆中应该是这个样子,如果有问题,欢迎指正。
3.2 变量定义和变量初始化
先解释下这2个概念的专业术语:
示例:
解释:
其实以上代码,在JS内部可是执行了2步,即:先定义,再初始化。
以上代码在JS内部执行的时候,是将定义和初始化分开执行:
四、升华
在上文中有个细节,我一直提起,就是:变量和函数提前。
我们知道函数其实也有两种(不止)定义方式:函数申明和函数表达式。
其中,函数表达式,又分为:匿名函数表达式 和 函数表达式。
顺便补下基础:
那对于
函数申明
和函数表达式
是不是都会提前呢?看下例子。补充说明下:
五、扩展
上文中提到了作用域(Scope),这里总结一个知识点,就是一个变量进入作用域的4种方式:
六、习题
好了,所有概念全部梳理完了,以下经常在面试中出现的习题,大家不放围观下。
1、开篇的题目
答案:undefined
2、触类旁通
答案:undefinedA
分析:
这个题目,如果大家按照变量hoist的方式拆分下,可能就明白了。
3、再补充一个
答案:0, 1
分析:
我们要牢记hoist是在当前作用域内被提前。
七、参考
The text was updated successfully, but these errors were encountered: