关于变量提升,以前在一些教程和书籍上都听到过,平时开发中也知道有这个规律,但是今天突然在一个公开课中听到时,第一反应时一脸懵逼,然后一百度,瞬间觉得好熟悉啊,差点被这个概念给唬住了,不信我给你看个栗子,你也会恍然大悟的:

(function(){
console.log(v);
var v = 'I love you';
console.log(v);
})()
// undefined I love you

    这就是一个典型的变量提升的例子了,规则是怎样的呢,我的理解是在一个作用域内,无论你在哪个地方声明的变量都会被提升到顶部,但不会赋值。像本例子中的v就是先被提升到了函数作用域的顶端,所以实际运行过程是这样的:

(function(){
var v = undefined;
console.log(v);
v = 'I love you';
console.log(v);
})()
// undefined I love you

    为什么会这样呢,我参考了别人的解释是因为js的运行机制:

js自上而下的执行过程分为两个词法分析和执行两个阶段:词法分析主要包括:分析形参、分析变量声明、分析函数声明三个部分.通过词法分析将我们写的js代码转成可以执行的代码,接下来才是执行。

    变量提升还有一种情况,就是函数,词法分析的时候关于函数声明的处理与变量声明的处理不太一致,会一步到位的给当前函数活动对象增加对应函数名的属性,并重写该方法。也就是不会像变量那样先赋值undefined了。说的有点绕,我们还是看代码,可以先自己看一下执行结果,再看下面的分析:

function a(){
var b = 'a';
function b(){
console.log('b')
}
alert(b)
}
a()

    简单说下,词法分析时对function b的处理:给当前函数活动对象obj增加属性b,并赋值。即:obj.a = function(){...}; 所以词法分析后的结果成了这个样子:

function a(){
var b = undefined;
b = function b(){
console.log('b')
}
b = 'a';
alert(b); // a
}
a()

    这个地方也只是我读别人观点的一种借鉴,但是我有点不太确定的是普通变量提升和函数提升同时进行时到底谁在最顶端?反正就目前我的认识变量提升的规律是清楚了,大提升提升的原理是因为JS运行机制的问题,为了尽量避免变量提升带来的一些困扰,日常开发中文名还是要养成先声明再使用的好习惯,尽量在函数开头把所有变量都声明出来。文中观点大都是个人理解,如有不对,欢迎指出!

参考文章: https://www.cnblogs.com/huilixieqi/p/6473572.html

关于JS中变量提升的规则和原理的一点理解的更多相关文章

  1. 关于JS中变量提升的规则和原理的一点理解(二)

    上篇文章中讲到变量提升和函数提升的先后顺序时蒙了,后来去查了一下资料,特别整理一下. 在<你不知道的JavaScript(上卷)>一书的第40页中写到:函数会首先被提升,然后才是变量. 书 ...

  2. js中变量提升(一个是变量,一个是函数表达式都会存在变量提升,函数声明不存在)

    一.变量提升 在ES6之前,JavaScript没有块级作用域(一对花括号{}即为一个块级作用域),只有全局作用域和函数作用域.变量提升即将变量声明提升到它所在作用域的最开始的部分.上个简历的例子如: ...

  3. js中变量提升和函数提升

    变量提升和函数提升的总结 我们在学习JavaScript时,会遇到变量提升和函数提升的问题,为了理清这个问题,现做总结如下,希望对初学者能有所帮助 我们都知道 var 声明的变量有变量提升,而 let ...

  4. 深入理解js的变量提升和函数提升

    一.变量提升 在ES6之前,JavaScript没有块级作用域(一对花括号{}即为一个块级作用域),只有全局作用域和函数作用域.变量提升即将变量声明提升到它所在作用域的最开始的部分.上个简历的例子如: ...

  5. JavaScript中变量提升是语言设计缺陷

    首先纠正下,文章标题里的 “变量提升” 名词是随大流叫法,“变量提升” 改为 “标识符提升” 更准确.因为变量一般指使用 var 声明的标识符,JS 里使用 function 声明的标识符也存在提升( ...

  6. 深入理解js的变量提升和函数提升(转)

    一.变量提升 在ES6之前,JavaScript没有块级作用域(一对花括号{}即为一个块级作用域),只有全局作用域和函数作用域.变量提升即将变量声明提升到它所在作用域的最开始的部分.上个简历的例子如: ...

  7. js中变量的声明

    大家都知道js中变量的声明是要提前的,下面有4个样例: 1.if(!"t" in window){  var t = 1; }       alert(t);答案是undefine ...

  8. php面试专题---1、php中变量存储及引用的原理

    php面试专题---1.php中变量存储及引用的原理 一.总结 一句话总结: 查看变量的存储结构可以安装xdebug扩展,用xdebug_debug_zval()方法,不推荐使用memory_get_ ...

  9. js中call和apply的实现原理

    js中call和apply的实现原理            实现call的思路: /* 还有就是call方法是放在Function().prototype上的也就是构造函数才有的call方法 (我门可 ...

随机推荐

  1. springboot+CXF开发webservice对外提供接口(转)

    文章来源:http://www.leftso.com/blog/144.html 1.项目要对外提供接口,用webservcie的方式实现 2.添加的jar包 maven: <dependenc ...

  2. IntelliJ IDEA 左侧列表设置忽略文件格式

    什么问题 idea 中设置忽略文件 Unity开发过程中使用Lua做逻辑开发 Unity会自动生成xx.meta文件 这种文件再使用Idea开发过程中没有用处 显示文件列表中会看着比较乱 如何设置 F ...

  3. 5.python函数

    一.递归函数 如果一个函数在内部调用自身,那么这个函数就叫做递归函数. 1. 必须有一个明确的结束条件: 2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少: 3.递归效率不高,递归层次过 ...

  4. NoSQL数据库

    NoSQL数据库 1.NoSQL简介 最初表示"反SQL"运动,用新型的非关系型数据库取代关系数据库:现在表示"Not only SQL"关系和非关系型数据库各 ...

  5. Struts2学习---result结果集

    这一章节主要介绍如何配置结果集,分为以下几个知识点: 结果集类型(result type) 全局结果集(global types) 动态结果集(dynamic type) 带有参数的结果集(type ...

  6. python学习日记:day11-----装饰器

    1,time模块 import time print(time.sleep())#让程序在执行到这个位置到时候停一会 print('哈哈哈') 获取当前时间 import time time.time ...

  7. Java中的UDP应用

    我在<JavaSE项目之聊天室>中通过遵守TCP协议的ServerSocket与Socket实现了聊天室的群聊窗口.同时,在介绍OSI与TCP/IP参考模型时,也曾提及TCP与UDP(全称 ...

  8. php实现MySQL读写分离

    MySQL读写分离有好几种方式 MySQL中间件 MySQL驱动层 代码控制 关于 中间件 和 驱动层的方式这里不做深究  暂且简单介绍下 如何通过PHP代码来控制MySQL读写分离 我们都知道 &q ...

  9. 获取两个时间节点的月份列表&&每个月份的开始时间及结束时间

    //Q:从今天起之前五个月的列表 date_default_timezone_set('PRC'); $time=strtotime('-5 month'); //包含本月 $begin = strt ...

  10. 房上的猫:JavaDoc注释

    //这是一个注释 /*   *这是一个演示程序   */ /**    *@这是JavaDoc注释.   */ JavaDoc注释 背景: javadoc是Sun公司提供的一个技术,它从程序源代码中抽 ...