在过去的课程里,我们学会了定义变量、定义函数,以及使用变量、使用函数。
对于变量的使用,有以下两种特殊情况需要注意:
- 当我们使用一个没有定义的变量时,会发生异常。
- 当我们使用一个未初始化的变量时,其值是undefined,而不会发生异常。
如下:
console.log(age) // age未定义,会发生异常
现在有下面这样一段代码,你看看能不能正常运行:
var age
console.log(age) // age已定义未初始化,会输出undefined
上述两个代码片段,第一个因age未定义,会发生异常,如下:
未定义异常第二个片段,定义了age便未初始化,会输出undefined,如下:
只定义不初始化好。上面两点非常的清晰你现在已经掌握了。现在看看下面的的代码:
console.log(age)
var age=18
推测一下,上述代码,运行会是什么结果?是发生未定义异常、还是undefined、还是输出18?我们来看一下运行结果:
运行结果
上述代码运行结果是 undefined。为什么?
在前面的课程中,我们提到过,JavaScript引擎处理脚本总共分为两个过程:
- 从头到尾一行一行扫描代码,分析语法,找出定义了哪些变量、函数。
- 从头到尾一行一行执行代码,以实现代码功能。
根据JavaScript引擎的两步处理步骤,我们来分析一下为什么上述代码输出的是undefined。上述代码的执行流程如下:
- 从头到尾扫描代码:
- 分析第一行代码,什么都没定义
- 分析第二行代码,扫描到需要定义一个age变量,所以定义一个age变量
- 从头到尾执行代码:
- 执行第一行代码,输出age,此时age已经在第1步中完成了定义,所以值是undefined。
- 执行第二行代码,age赋值为18。
因为JavaScript处理代码分为两步,所以在同一作用域内定义的变量,在本作用域内任意地方都能引用,包括定义之前。
JavaScript的这种特性叫做声明提升(hoisting)。和变量一样,JavaScript中的函数也有这种特性。下面的例子说明了这一点:
sayHi();
function sayHi() // 全局作用域中定义了sayHi方法
{
console.log("Hello world!")
}
可以看到,第一行在全局作用域调用了sayHi函数,第二行再定义sayHi函数。运行结果如下:
运行结果可以看到,虽然提前调用了saiHi方法,但依旧调用成功。
好,这一节讲完了。这一节内容是高频面试知识点,希望你能掌握。后续还有很多技巧需要你慢慢学习。
什么是匿名函数?什么是函数默认参数?什么是函数堆栈?
请继续关注我的课程,我将在后续课程中为大家解答上述问题。
想学计算机技术吗?需要1对1专业级导师指导吗?想要团队陪你一起进步吗?欢迎加我为好友!
我的微信
网友评论