当前位置: 首页 > news >正文

JavaScript 内功心法——变量提升及函数提升

在看一些面试题的时候,会发现有些答案往往不是我们想的那么简单,有些时候会有意想不到的结果,这些答案有可能就是因为变量和函数提升导致的。下面我们就简单看一下什么是变量提升,什么是函数提升。

1. 变量提升

变量不管在任何地方声明,js 引擎在编译时都会发生变量提升。

例:

console.log(a); // undefined

var a = 2;
复制代码

在定义变量 a 之前打印 a,并不会报Uncaught ReferenceError: i is not defined的错,而是输出undefined,因为var a = 2会进行变量提升,会被引擎解析成如下代码:

var a;

console.log(a); // undefined

a = 2;
复制代码

var a = 2,js 引擎其实会分解成var aa = 2两个单独的声明,第一个是编译阶段,第二个是执行阶段。

再用另外一个例子说明一下变量提升,变量如果在不符合条件的 if 语句中定义,也会发生变量提升。

例:

function test() {
  if (false) {
    var i = 100;
  }
  console.log(i); // undefined
}
test();
复制代码

虽然是在判断条件中定义的变量,并且当前条件也不满足,但是在访问定义的变量时,会提示 undefined,而不是Uncaught ReferenceError: i is not defined报错,充分说明了在判断条件中定义的变量,即时没有执行到判断条件中,变量也会提前声明。

2. 函数提升

函数声明和变量声明一样,在被执行前都会进行“移动”处理,“移动”到各自作用域的最顶端,也就是所谓的提升。

在定义函数之前使用函数,函数也会执行。

例:

test();

function test() {
  var i = 1;
  console.log(i); // 1
}
复制代码

这种情况在我们开发中会经常遇到,我们有的时候会把函数定义到执行函数的下面,也不会报错,不报错的原因就在于此,函数进行了提升。

虽然函数和变量都会提升,但是函数提升优于变量提升

例:

foo(); // 1

function foo() {
  console.log(1);
}

var foo = function() {
  console.log(2);
};
复制代码

会输出 1 而不是 2,因为引擎会解析成一下代码:

function foo() {
  console.log(1);
}

var foo; // 被忽略了

foo(); // 1

foo = function() {
  console.log(2);
};
复制代码

var foo 是重复声明,所以被忽略了,因为函数声明优于变量声明。

如何区分函数声明和函数表达式:function 关键字出现的位置(不是一行,是整个声明的位置),如果 function 是声明中的第一个词,就是函数声明,否则就是函数表达式。

其他心法目录:

后续会将自己总结的内功心法大全慢慢放出来,其中包括 JS 作用域,执行上下文,this 指向问题,原型链,闭包...,供自己和他人学习。

  • JavaScript 内功心法——词法作用域及动态作用域
  • JavaScript 内功心法——执行上下文
  • JavaScript 内功心法——作用域链
  • JavaScript 内功心法——EventLoop
  • JavaScript 内功心法——数据类型
  • JavaScript 内功心法——原型与原型链

相关文章:

  • 获取百度网盘真实地址
  • 鸡你太美
  • openshift上使用devicemapper
  • POJ-1195-Mobile phones
  • 2019 全球智博会即将开幕,五大惊喜抢先看!| 智博会
  • 5G重新定义汽车工业:它是汽车智能化的关键技术吗?| 2019 上海车展
  • linux目录结构特点
  • 基于StarlingX的边缘计算机器学习优化
  • Mysql查询语句的运行流程
  • 跑步书籍推荐 --- 跑步指南
  • 2019阿里云企业服务器配置选择教程!【 可供新手小白参考】
  • CSS文本超出2行就隐藏并且显示省略号
  • “打开潜意识 拥抱心灵智慧” 51CTO心理师线下沙龙课北京站
  • 生成树协议(STP)
  • Robust PCA via Outlier Pursuit
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • [ JavaScript ] 数据结构与算法 —— 链表
  • [译]CSS 居中(Center)方法大合集
  • [译]Python中的类属性与实例属性的区别
  • 《微软的软件测试之道》成书始末、出版宣告、补充致谢名单及相关信息
  • bearychat的java client
  • CentOS6 编译安装 redis-3.2.3
  • iOS小技巧之UIImagePickerController实现头像选择
  • java第三方包学习之lombok
  • Java教程_软件开发基础
  • jdbc就是这么简单
  • Markdown 语法简单说明
  • Node.js 新计划:使用 V8 snapshot 将启动速度提升 8 倍
  • PHP CLI应用的调试原理
  • Python_网络编程
  • vue-router 实现分析
  • 不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...
  • 翻译--Thinking in React
  • 构建二叉树进行数值数组的去重及优化
  • 基于Android乐音识别(2)
  • 基于遗传算法的优化问题求解
  • 那些被忽略的 JavaScript 数组方法细节
  • 前端代码风格自动化系列(二)之Commitlint
  • 人脸识别最新开发经验demo
  • 听说你叫Java(二)–Servlet请求
  • 我有几个粽子,和一个故事
  • 一个普通的 5 年iOS开发者的自我总结,以及5年开发经历和感想!
  • 移动端解决方案学习记录
  • 如何用纯 CSS 创作一个菱形 loader 动画
  • 专访Pony.ai 楼天城:自动驾驶已经走过了“从0到1”,“规模”是行业的分水岭| 自动驾驶这十年 ...
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • ​flutter 代码混淆
  • # 睡眠3秒_床上这样睡觉的人,睡眠质量多半不好
  • #快捷键# 大学四年我常用的软件快捷键大全,教你成为电脑高手!!
  • (C语言)逆序输出字符串
  • (附源码)springboot 智能停车场系统 毕业设计065415
  • (附源码)springboot青少年公共卫生教育平台 毕业设计 643214
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (原+转)Ubuntu16.04软件中心闪退及wifi消失