前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >函数与变量的优先级

函数与变量的优先级

作者头像
OECOM
修改2021-02-05 09:30:48
7090
修改2021-02-05 09:30:48
举报
文章被收录于专栏:OECOMOECOM

我们之前说过变量声明会出现变量提升的情况,这个问题说的已经很多了,但是我还是想在啰嗦一下。直觉上我们都会认为 JavaScript 是单线程语言,代码在执行时是由上到下一行一行执行的。但实际上这并不完全 正确,有一种特殊情况会导致这个假设是错误的,这种特殊情况不包括异步。

代码语言:javascript
复制
a = 2;
var a;
console.log( a );

那么这个a应该输出什么呢,很多人认为会输出undefined,因为后面的声明变量将前面的覆盖了。事实上其结果却是输出2,就是因为变量提升的原因。我们再看一下下面这段代码

代码语言:javascript
复制
console.log(a);
var a = 2;

鉴于上一个代码片段所表现出来的某种非自上而下的行为特点,你可能会认为这个代码片段也会有同样的行为而输出 2。还有人可能会认为,由于变量 a 在使用前没有先进行声明,因此会抛出 ReferenceError 异常。

不幸的是两种猜测都是不对的。输出来的会是 undefined,原因也是因为变量提升的问题。

解释

JavaScript引擎会在解释 JavaScript 代码之前首先对其进行编译。编译阶段中的一部分工作就是找到所有的声明,并用合适的作用域将它们关联起来。因此,正确的思考思路是,包括变量和函数在内的所有声明都会在任何代码被执行前首先被处理。当你看到var a = 2; 时,可能会认为这是一个声明。但 JavaScript 实际上会将其看成两个声明:var a;a = 2;。第一个定义声明是在编译阶段进行的。第二个赋值声明会被留在原地等待执行阶段。

代码语言:javascript
复制
var a;
a = 2;
console.log( a );

实际的执行效果如上代码所示。

函数声明

在写代码过程中,我们会发现无论我的函数声明写在哪都可以调用,原因就在于函数的声明也存在提升的现象。

代码语言:javascript
复制
oecom();
function oecom(){
    console.log("oecom")
}

这种方式去执行时不会报任何错误的,还会顺利的输出oecom。原因就在于函数的声明会在最开始声明,形成如下代码:

代码语言:javascript
复制
function oecom(){
    console.log("oecom")
}
oecom();

我们再来看另外一中形式

代码语言:javascript
复制
oecom();
var oecom = function(){
    console.log("oecom")
}
函数与变量的优先级
函数与变量的优先级

通过上图我们可以发现报错了。原因在于函数声明会被提升,但是函数表达式却不会被提升。同时也要记住,即使是具名的函数表达式,名称标识符在赋值之前也无法在所在作用域中。

代码语言:javascript
复制
oecom();
var oecom = function(){
    console.log("oecom")
}
函数与变量的优先级
函数与变量的优先级

函数优先

函数声明和变量声明都会被提升。但是一个值得注意的细节(这个细节可以出现在有多个“重复”声明的代码中)是函数会首先被提升,然后才是变量。

代码语言:javascript
复制
foo(); // 1
var foo;
function foo() {
 console.log( 1 );
}
foo = function() {
 console.log( 2 );
};

代码执行结果会输出 1 而不是 2 !这个代码片段会被引擎理解为如下形式:

代码语言:javascript
复制
function foo() {
 console.log( 1 );
}
foo(); // 1
foo = function() {
 console.log( 2 );
};

注意,var foo 尽管出现在 function foo()... 的声明之前,但它是重复的声明(因此被忽略了),因为函数声明会被提升到普通变量之前。尽管重复的 var 声明会被忽略掉,但出现在后面的函数声明还是可以覆盖前面的。

代码语言:javascript
复制
foo(); // 3
function foo() {
 console.log( 1 );
}
var foo = function() {
 console.log( 2 );
};
function foo() {
 console.log( 3 );
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-12-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 解释
  • 函数声明
  • 函数优先
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档