JavaScript 变量提升
JavaScript 变量提升
JavaScript 中,函数及变量的声明都将被提升到函数的最顶部。
JavaScript 中,变量可以在使用后声明,也就是变量可以先使用再声明。
这几天在刷题的过程中经常碰到关于变量提升和作用域的问题。
作用域问题,在之前的博客有写过:Mr.J--JS学习(闭包私有化)
通常JS引擎会在正式执行之前先进行一次预编译,在这个过程中,首先将变量声明及函数声明提升至当前作用域的顶端,然后进行接下来的处理。(注:当前流行的JS引擎大都对源码进行了编译,由于引擎的不同,编译形式也会有所差异,我们这里说的预编译和提升其实是抽象出来的、易于理解的概念)。
var val = 12;
function foo(){console.log(val);var val = 20;console.log(val);
}
foo();
我刚开始看这段代码,以为是作用域的问题,然后认为输出是: 12 20;
但是这段代码通过变量提升,可以转化成以下的代码:
var val = 12;
function foo(){var val;console.log(val);var val = 20;console.log(val);
}
foo();
答案很明显了:undefined 20
变量提升:函数声明和变量声明总是会被解释器悄悄地被"提升"到方法体的最顶部。
JavaScript 初始化不会提升
var x = 5; // 初始化 xelem = document.getElementById("demo"); // 查找元素
elem.innerHTML = x + " " + y; // 显示 x 和 yvar y = 7; // 初始化 y
在这段代码中,在使用y的值之后出现了y值的初始化,转化代码格式:
var x = 5; // 初始化 x
var y; // 声明 yelem = document.getElementById("demo"); // 查找元素
elem.innerHTML = x + " " + y; // 显示 x 和 yy = 7; // 设置 y 为 7
最终输出:x 为:5,y 为:undefined
函数提升
function bar() {foo(); // output: I am hoistedfunction foo() {console.log('I am hoisted');}
}bar();
为什么函数可以在声明之前就可以调用,并且跟变量声明不同的是,它还能得到正确的结果,其实引擎是把函数声明整个地提升到了当前作用域的顶部,预编译之后的代码逻辑如下:
// 预编译之后
function bar() {function foo() {console.log('I am hoisted');}foo(); // output: I am hoisted
}bar();
其实这个就是执行上下文的有关问题了。好多学习JavaScript的人一般不会注意变量提升的问题,这样就会导致代码极其容易出错。
之前写过相关的博客,博客链接:一篇文章让你理解面试难点:执行上下文(干货满满(附面试题))
同样,如果出现同名函数,将会进行函数的覆盖,即后者覆盖前者:
function bar() {function foo() {console.log(1);}foo(); // output: 2function foo() {console.log(2);}
}bar();
为什么要进行提升
由于第一代JS虚拟机中的抽象纰漏导致的,编译器将变量放到了栈槽内并编入索引,然后在(当前作用域的)入口处将变量名绑定到了栈槽内的变量。(注:这里提到的抽象是计算机术语,是对内部发生的更加复杂的事情的一种简化。)
然后,Dmitry Soshnikov又提到了函数提升,他提到了相互递归(就是A函数内会调用到B函数,而B函数也会调用到A函数)。函数提升就是为了解决相互递归的问题,大体上可以解决像ML语言这样自下而上的顺序问题。
总结
function jsFun6(){ //函数声明和函数表达式的区别test1();//函数声明提升,在执行代码之前会先读取函数声明,不会报错function test1(){//函数声明方式创建函数alert("测试1");}//test2();报错,函数还不存在console.log(test2)//不会报错,变量提升只是提升变量的声明,并不会把赋值也提升上来,输出undefinedvar test2=function(){alert("测试2");};//使用函数表达式创建一个匿名函数(实际是以变量test3命名的函数)test2();//不会报错,以创建函数var test3=function(){alert("测试3");}();//加了括号立即执行var test4 = 12;// !注意看,一旦变量被赋值后,将会输出变量//函数提升优先级高于变量提升,所以函数先提升,然后变量提升覆盖之前的函数声明,表 //现为变量function test4() {alert("测试4"); }console.log(test4); //12var test5="test5_1";(function(){//js中的变量搜索顺序:找变量时,先找局部变量,如果没有局部变量;再找全局变量。alert(test5);//此时的test5为局部变量的提升,undefinedvar test5="test5_2";})();}
只要理解了执行上下文,对于变量提升就会一下看懂。一篇文章让你理解面试难点:执行上下文(干货满满(附面试题))
JavaScript 变量提升相关推荐
- JavaScript变量提升
JavaScript变量提升 在JavaScript中变量声明与函数声明都会被提升到作用域顶部,优先级依次为: 函数声明 变量声明 变量赋值. 变量提升 var的变量提升 console.log(a) ...
- JavaScript变量提升机制
JavaScript变量提升机制 Js代码执行前(栈内存)还做了一件事那就是变量提升,Js会在所有var function等关键字的提前声明或者定义.. 看以下的代码: console.log(a); ...
- php变量 声明提升,JavaScript 变量提升
JavaScript 变量提升 JavaScript 中,函数及变量的声明都将被提升到函数的最顶部. JavaScript 中,变量可以在使用后声明,也就是变量可以先使用再声明. 以下两个实例将获得相 ...
- javascript变量提升/函数提升
首先 javascript 是一种弱类型.动态的.解释型的脚本语言. 弱类型:类型检查不严格,偏向于容忍隐式类型转换. 强类型:类型检查严格,偏向于不容忍隐式类型转换. 动态类型:运行的时候执行类型检 ...
- JavaScript变量提升(Hoisting)详解
文章出自个人博客https://knightyun.github.io/2019/09/02/js-hoisting,转载请申明. 概念 变量提升是 JavaScript 的一种执行机制,大致就是字面 ...
- Javascript变量提升与暂时性死区
暂时性死区:在ES6之前,使用 typeof 运算符操作一个未声明的变量时,不会报错,该变量的值以 undefined 作处理.而在ES6之后,使用ES6的变量声明方法(let, const, cla ...
- javaScript变量提升以及函数提升
变量的声明赋值 var a = 1; 上面的代码先声明变量 a,然后在变量 a 与数值 1 之间建立引用关系,称为将数值 1 "赋值"给变量 a.以后,引用变量名 a 就会得到数值 ...
- JavaScript 变量提升的作用
文章目录 前言 预解析时期 正式执行时期 一.举例 1. 函数提升-求以下代码执行结果 2. 函数提升-求以下代码执行结果 3.函数提升-求以下代码的结果 4.变量提升-求以下代码的结果 5.clas ...
- JavaScript 变量提升(hoisting)
借鉴了一下菜鸟教程官网的解说. JavaScript 中,(1)函数及变量的声明都将被提升到函数的最顶部:(2)变量可以在使用后再进行声明. 变量提升:解释器总是会悄悄地把函数声明和变量声明" ...
最新文章
- SQL Server 2008最直观的变化上(三)
- 关于ie中easyui form组件load事件无法多次加载数据
- 【数据库系统概论】考研第二部分重点分析【2.2】
- linux OOM-killer机制(杀掉进程,释放内存)
- 操作系统:第二章 进程管理1 - 进程、线程
- java清除浏览器记录_java – 如何在Selenium测试中清除浏览器缓存
- c++ 怎样连接两个链表_LeetCode | 链表的入口,一文帮你搞定“环形链表”(python版,最简单解析)...
- 在飞音G801上运行OpenWRT+Asterisk
- leetcode139 单词拆分
- 膨胀的木棍(信息学奥赛一本通-T1246)
- java的Random类
- ios中获取各种文件的目录路径方法
- mysql改变授权_mysql8使用grant授权修改
- C语言——蔡勒(Zeller)公式的使用
- 基于 Mybatis 和 Springboot 的后台管理系统 BootDo | 软件推介
- 中国联通开放号码标记一键查询与清除服务
- 华为HCNA之OSPF多区域配置实验
- 发射极正偏,集电极反偏
- 【论文阅读】Multi-Modal Sarcasm Detection 图文反讽识别
- 无线路由器的基础配置(一)