详解javascript 变量提升(Hoisting)


Posted in Javascript onMarch 12, 2019

简介

“变量提升”意味着变量和函数的声明会在物理层面移动到代码的最前面,但这么说并不准确。

实际上变量和函数声明在代码里的位置是不会动的,而是在编译阶段被放入内存中。

声明变量的方法

var、let、const

不用以上关键字直接赋值的变量会挂载与windows环境下;

let a=9
const a=1
var a=6
c=5

声明函数的方法

javascript中声明函数的方法有两种:函数声明式和函数表达式。

//函数声明
function say(){
  console.log('hello') 
}

//函数表达式
var say=function (){
  console.log('hello') 
}

提升的好处

JavaScript 在执行任何代码段之前,将函数声明放入内存中的优点之一是,这允许你可以在在声明该函数之前使用一个函数。

/*** 正确的方式:先声明函数,再调用函数 (最佳实践)*/
function catName(name) {
  console.log("我的猫名叫 " + name);
}
catName("Tigger");
/*以上代码的执行结果是: "我的猫名叫 Tigger"*/


/*** 不推荐的方式:先调用函数,再声明函数 */
catName("Chloe");
function catName(name) {
  console.log("我的猫名叫 " + name);
}
/*代码执行的结果是: "我的猫名叫 Chloe"*/

提升规则

  • var 声明的变量,提升时只声明,不赋值,默认为undefined;不用关键字直接赋值的变量不存在提升(demo1)
  • 函数提升会连带函数体一起提升,不执行;(deom2)
  • 预解析的顺序是从上到下;(demo4)
  • 函数的优先级高于变量,函数声明提前到当前作用域最顶端;(deom3)
  • 变量重名,提升时不会重复定义;在执行阶段后面赋值的会覆盖上面的赋值;(demo4)
  • 函数重名,提升时后面的会覆盖前面;(demo5)
  • 函数和变量重名,提升函数,不会重复定义,变量不会覆盖函数;在执行阶段后面赋值的会覆盖上面的赋值;(demo8)
  • 用函数表达式声明函数,会按照声明变量规则进行提升;(deom6)
  • 函数执行时,函数内部的变量声明和函数声明也按照以上规则进行提升;(deom7)
  • let、const不存在提升;(demo9、demo10)
/**demo1**/
console.log('a=',a) //a=undefined
console.log('b=',b) // Uncaught ReferenceError: b is not defined
var a=1
b=6


/**deom2**/
console.log('a=',a) // a=function a() {console.log("func a()")}
function a() {
console.log("func a()")
}

/**deom3**/
console.log('a=',a) // a=function a() {console.log("fun a")}
var a=3
var a=4

function a(){
console.log("fun a")
}
var a=5
var a=6
console.log("a=",a) // a=6

 

/**deom4**/
console.log('a=',a) // a=undefined
var a =2
console.log('a=',a) //
var a =3
var a =4
console.log('a=',a) // a=4
console.log('b=',b) //b= undefined
var b='b1'


/**deom5**/
console.log('a=',a) // a=function a() {console.log("a2")}
function a(){
console.log("a1")
}
function a(){
console.log("a2")
}
console.log('a=',a) // a=function a() {console.log("a2")}


/**deom6**/
console.log('a=',a) // a=undefined
var a=function(){console.log('a1')}
var a=3
var a=4
var a=5
console.log(a)
var a=function(){console.log('a2')}
console.log('a=',a) // a= ƒ (){console.log('a2')}


/**deom7**/
console.log('b=',b)
var a=3
function b(i){
  console.log('a=',a)
  var a=4
  function a(){
    console.log('fun a')
  }
  console.log('a=',a)
}
b()


/**demo8**/
console.log('a=',a) //a= function a(){ console.log('fun a')}
var a=2
function a(){
  console.log('fun a')
}
console.log('a=',a) // a=2
var a=3
var a=4
var a=5
console.log('a=',a) // a=5


/**demo9**/
console.log('a=',a) //Uncaught ReferenceError: a is not defined
let a=4


/****/
<!--demo10-->
console.log('b=',b) // Uncaught ReferenceError: b is not defined
const b=5

参考资料

MDN

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Jquery Ajax 学习实例2 向页面发出请求 返回JSon格式数据
Mar 15 Javascript
基于jquery的获取mouse坐标插件的实现代码
Apr 01 Javascript
javascript获取网页中指定节点的父节点、子节点的方法小结
Apr 24 Javascript
javascript实现点击单选按钮链接转向对应网址的方法
Aug 12 Javascript
js实现上传文件添加和删除文件选择框
Oct 24 Javascript
Bootstrap基本插件学习笔记之按钮(21)
Dec 08 Javascript
bootstrap多种样式进度条展示
Dec 20 Javascript
vue.js整合mint-ui里的轮播图实例代码
Dec 27 Javascript
一种angular的方法级的缓存注解(装饰器)
Mar 13 Javascript
浅谈React的最大亮点之虚拟DOM
May 29 Javascript
Vuex的实战使用详解
Oct 31 Javascript
JavaScript实现模态对话框实例
Jan 13 Javascript
NestJs 静态目录配置详解
Mar 12 #Javascript
JavaScript使用小插件实现倒计时的方法讲解
Mar 11 #Javascript
30分钟精通React今年最劲爆的新特性——React Hooks
Mar 11 #Javascript
记录一次完整的react hooks实践
Mar 11 #Javascript
es6数值的扩展方法
Mar 11 #Javascript
Vue实现一个图片懒加载插件
Mar 11 #Javascript
使用Jenkins部署React项目的方法步骤
Mar 11 #Javascript
You might like
让你成为更出色的PHP开发者的10个技巧
2011/02/25 PHP
PHP函数按引用传递参数及函数可选参数用法示例
2018/06/04 PHP
PHP实现负载均衡的加权轮询方法分析
2018/08/22 PHP
PHP类与对象后期静态绑定操作实例详解
2018/12/20 PHP
又一个图片自动缩小的JS代码
2007/03/10 Javascript
javascript 弹出层组件(升级版)
2011/05/12 Javascript
jQuery源码分析-02正则表达式 RegExp 常用正则表达式
2011/11/14 Javascript
jQuery之ajax删除详解
2014/02/27 Javascript
基于jQuery实现网页进度显示插件
2015/03/04 Javascript
浅谈jquery中delegate()与live()
2015/06/22 Javascript
Servlet实现文件上传,可多文件上传示例
2016/12/05 Javascript
JS实现的简单轮播图运动效果示例
2016/12/22 Javascript
vue-cli脚手架config目录下index.js配置文件的方法
2018/03/13 Javascript
解决angular2在双向数据绑定时[(ngModel)]无法使用的问题
2018/09/13 Javascript
JS无限级导航菜单实现方法
2019/01/05 Javascript
快速了解Node中的Stream流是什么
2019/02/13 Javascript
vue解决使用$http获取数据时报错的问题
2019/10/30 Javascript
详解vue3.0 diff算法的使用(超详细)
2020/07/01 Javascript
JS实现小米轮播图
2020/09/21 Javascript
使用Python的Scrapy框架编写web爬虫的简单示例
2015/04/17 Python
浅谈python中的变量默认是什么类型
2016/09/11 Python
浅谈终端直接执行py文件,不需要python命令
2017/01/23 Python
pyqt5简介及安装方法介绍
2018/01/31 Python
基于Python实现下载网易音乐代码实例
2020/08/10 Python
OpenCV+python实现膨胀和腐蚀的示例
2020/12/21 Python
加拿大消费电子和手机购物网站:The Source
2017/01/28 全球购物
init进程的作用
2015/08/20 面试题
护士自荐信怎么写
2013/10/18 职场文书
部队学习十八大感言
2014/01/11 职场文书
学校地质灾害防治方案
2014/06/10 职场文书
应届生求职信范文
2014/06/30 职场文书
教师群众路线教育实践活动个人对照检查材料
2014/11/04 职场文书
2015年秋季校长开学典礼致辞
2015/07/29 职场文书
安全教育主题班会总结
2015/08/14 职场文书
linux下安装redis图文详细步骤
2021/12/04 Redis
SpringCloud超详细讲解Feign声明式服务调用
2022/06/21 Java/Android