关于JS中变量提升的规则和原理的一点理解

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

(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

原文地址:https://www.cnblogs.com/wancheng7/p/8306711.html

时间: 2024-08-03 22:46:09

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

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

上篇文章中讲到变量提升和函数提升的先后顺序时蒙了,后来去查了一下资料,特别整理一下. 在<你不知道的JavaScript(上卷)>一书的第40页中写到:函数会首先被提升,然后才是变量. 书中的一个代码示例是: foo(); //1 var foo; function foo() { console.log(1); } foo = function() { console.log(2); } 这个例子相对比较好理解,就是foo这个函数会先被声明再作用域的开始部分,实际上这个代码片段会被引擎理解为

js中变量提升

1 var v='Hello World'; 2 (function(){ 3 alert(v); 4 var v='I love you'; 5 })() 会出现alert出来的是undefined,原因是因为在函数域里定义一个和外部变量一样名称的变量时,变量的声明会提升至第一句,赋值则不会变.所以上述语句其实是这样执行的 var v='Hello World'; (function(){ var v; alert(v); v='I love you'; })()

js中变量名提升和函数名提升

首先,js中变量没有块级作用域,但是有函数作用域,即只有函数可以约数变量的作用域. 并且,函数的实质也是一个变量,所以可以改变它的值,即赋值.所以变量名提升和函数名提升非常相像. 1.变量名的提升发生在函数内部.看下面的例子.说明:第一个因为弹出undefined,相当于在上面定义了var num;因为函数内部,定义了var num=20:就相当于在一开始定义了var num;这就是变量名的提升. var num = 10; function func() { alert(num); //und

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

一.变量提升 在ES6之前,JavaScript没有块级作用域(一对花括号{}即为一个块级作用域),只有全局作用域和函数作用域.变量提升即将变量声明提升到它所在作用域的最开始的部分.上个简历的例子如: 1 2 3 4 5 6 7 8 9 10 console.log(global); // undefined var global = 'global'; console.log(global); // global function fn () { console.log(a); // unde

PHP和JS中变量作用域

一,PHP中变量作用域 对于大多数PHP的变量只有一个作用域.在用户自定义函数里采用局部变量作用域.所有的函数内使用的变量被设置为局部变量.例如: <?php $a=1; function test() { echo $a; } test(); ?> 这段程序不会输出任何的东西因为echo语句要输出局部变量 $a ,而函数内的 $a 从未被赋过值.你可能注意到和C语言有点小小的区别,C中全局变量可以直接在函数内引用,除非它被一个局部变量所覆盖.因为这使得人们可能不注意修改了全局变量的值.在PH

js中变量的声明

大家都知道js中变量的声明是要提前的,以下有4个例子: 1.if(!"t" in window){ var t = 1; } alert(t);答案是undefined,为什么呢,就是因为变量声明提前了,所以t是在window对象里面的,但是没有走下面的判断,所以并没有赋值,答案就是undefine 2.var num = 100; function fn(){ var num = num + 1; return num; } falert(n());答案依然是NaN,因为在函数体内部

JavaScript中变量提升------Hoisting

本文转自 damonlan的文章 http://www.cnblogs.com/damonlan/archive/2012/07/01/2553425.html 前言 因为我在写这文章的时候,百度里找资料,找到了园友的一篇文章,写的很好,可是我写了又不想放弃,所以就在里面拿了很多东西过来!~~ [翻译]JavaScript Scoping and Hoisting 希望得到大家谅解. 因为这个问题很是经典,而且容易出错,所以在介绍一次.哈哈.莫怪哦. 一.案发现场 我们先看一段很简单的代码: v

js中变量含(参数、数组)作用域传递问题

js没有块级作用域(你可以自己闭包或其他方法实现),只有函数级作用域和全局作用域,函数外面的变量函数里面可以找到使用,函数里面的变量外面无法访问到. 写这个是因为ES6中的一个例子开始的.首先看下例子 var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 10 var a = []; for (let i = 0; i < 10; i++) { a[i] =

关于js的变量提升问题

1.关于变量提升: 例子一:console.log(a) //undifined; var a=0; 例子二: console.log(a)  //undifined; if(true){ var a=0; } console.log(a)  //0; 例子三: console.log(a) //undifined; if(!true){ var a=0; } console.log(a) //undifined; 以上:只要js中声明了变量,不管什么条件,都会自动提升到代码最开始的位置: 迷惑