JavaScript-----11.预解析
1.预解析
1.1引子
//1问
console.log(num);//报错 num未定义
//2问
console.log(num); //undefined 未报错
var num = 10;
//3问
fun();//11 未报错
function fun() {
console.log(11);
}
//把fun();放在后面、前面都不会报错
//4问
fun1();//报错 fun1 is not a function
var fun1 = function() {
console.log(22);
}
//把fun1();放在后面就不会报错
//综上,问2和文4都比较奇怪
- Js代码是由浏览器中的js解析器来执行的。js解析器在运行js代码的时候分为两步:预解析和代码执行。
- 预解析:js引擎会把js里面所有的var、function(这里指函数声明,不包括函数表达式)提升到当前作用域的最前面。
- 代码执行:按照代码书写的顺序从上往下执行
2.变量预解析和函数预解析
预解析分为变量预解析(变量提升)和函数预解析(函数提升)
2.1 变量提升 就是把所有的变量声明提升到当前作用域的最前面,不提升赋值操作。
对于之前的“问2”
//2问
console.log(num); //undefined 未报错
var num = 10;
相当于执行了以下代码
var num;
console.log(num); //undefined
num = 10;
对于之前的“问4”
//4问
fun1();//报错 fun1 is not a function
var fun1 = function() {
console.log(22);
}
//把fun1();放在后面就不会报错
相当于执行了以下代码
var fun1;
fun1();//报错 fun1 is not a function
fun1 = function() {
console.log(22);
}
值得注意的是这里的fun1是变量名,不是函数名,这里是函数表达式,是匿名函数。
2.2 函数提升 就是把所有的函数声明(注意是函数声明,不是函数表达式)提升到当前作用域的最前面, 不调用函数。
这就可用说明为什么在“问3”中,函数的fun();放在前后都不会报错,对于之前的问“问3”
fun();//11 未报错
function fun() {
console.log(11);
}
相当于执行了以下代码
function fun() {
console.log(11);
}
fun();//11 未报错
注意:由于函数表达式无法进行函数提升,所以函数表达式的调用必须写在函数表达式的下面
3.预解析案例
//案例1 会输出什么
var num = 10;
fun();
function fun() {
console.log(num);
var num = 20;
}
相当于执行了以下代码
var num;
function fun() {
var num;
console.log(num); //undefined
num = 20;
}
num = 10;
fun();
//案例2
var num = 10;
function fn() {
console.log(num);
var num = 20;
console.log(num);
}
fn();
相当于执行了以下代码
//相当于执行以下代码
//由内而外地完成变量提升,在根据链式查找法,得到输出的结果
var num;
function fn() {
var num;
console.log(num); //undefined
num = 20;
console.log(num); //20
}
num = 10;
fn();
//案例3
var a = 18;
f1();
function f1() {
var b = 9;
console.log(a);
console.log(b);
var a = '123';
}
相当于执行了以下代码
//相当于执行了以下代码
var a;
function f1() {
var b;
var a;
b = 9;
console.log(a); //undefined
console.log(b); //9
a = '123';
}
a = 18;
f1();
小tips:
var a = b = c = 9;
相当于
var a=9;
b=9;
c=9;
集体声明
var a = 9,b = 9,c = 9;
才相当于
var a = 9;
var b = 9;
var c = 9;
//案例4
f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {
var a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}
相当于执行以下代码
//相当于执行以下代码
function f1() {
var a;
a = b = c = 9;
console.log(a); //9
console.log(b); //9
console.log(c); //9
}
f1();
console.log(c); //9
console.log(b); //9
console.log(a); //报错 a is not defined
案例总结:先将代码按照预解析排列好,再按照作用域链去查找结果即可。
JavaScript-----11.预解析的更多相关文章
- 从var func=function 和 function func()区别谈Javascript的预解析机制
var func=function 和 function func()在意义上没有任何不同,但其解释优先级不同:后者会先于同一语句级的其他语句. 即: { var k = xx(); function ...
- javaScript中的小细节-script标签中的预解析
首先介绍预解析,虽然预解析字面意思很好理解,但是却是出坑出的最多的地方,也是bug经常会有的地方,利用好预解析的特性可以解决很多问题,并且提高代码的质量及数量,浏览器在解析代码前会把变量的声明和函数( ...
- JavaScript函数之作用域 / 作用链域 / 预解析
关于作用域和作用链域的问题,很多文章讲的都很详细,本文属于摘录自己觉得对自己有价值的部分,留由后用,仅供参考,需要查看详细信息请点击我给出的原文链接查看原文件 做一个有爱的搬运工~~ -------- ...
- JavaScript的变量预解析特性
JavaScript是解释型语言是毋庸置疑的,但它是不是仅在运行时自上往下一句一句地解析的呢?事实上或某种现象证明并不是这样的,通过<JavaScript权威指南>及网上相关资料了解到,J ...
- js的预解析
在ES6之前,变量使用var声明,会存在变量的预解析(函数也有预解析).ES6引了let和const,但是现阶段ES6并没有完全普及,而且很多比较老的代码都还是按照ES5的标准甚至是ES3的标准来书写 ...
- js 预解析
前言 JavaScript是解释型语言是毋庸置疑的,但它是不是仅在运行时自上往下一句一句地解析的呢? 事实上或某种现象证明并不是这样的,通过<JavaScript权威指南>及网上相关资料了 ...
- javascript解析机制——预解析
JavaScript解析机制是什么? JavaScript解析过程分为两个阶段,一个是编译阶段,另外一个就是执行阶段. * 编译阶段 编译阶段就是我们常说的JavaScript预解析( ...
- javascript的执行和预解析
很久以前遇到过一个面试题目,的的确确是面试官问我的问题,下面是这个问题的代码部分.由于年少无知,没有回答上,被无情pass了. var u ='hello world'; ;(function(){ ...
- javascript预解析和作用域
JavaScript解析过程分为两个阶段: 一是:编译阶段.就是JavaScrip预解析阶段,在这个阶段JavaScript解析器将完成把JavaScript脚本代码转换到字节码; 二是:执行阶段.在 ...
- Javascript预解析、作用域、作用域链
最近在看js的一些资料,总结一下昨晚看到的js作用域方面的知识,不准确的地方希望留言指正! 先看片段js代码如下: < script type="text/javascript&quo ...
随机推荐
- CORS on Nginx
https://enable-cors.org/server_nginx.html # # Wide-open CORS config for nginx # location / { if ($re ...
- linux-history、find、
1.history:查看历史记录 -c:清除历史命令记录 -d:删除某一条使用过的命令,-d后跟命令的序列号 2.find:在目录结构中搜索文件 -type:后面跟文件的类型,d表示目录,f表示文件 ...
- JS基础-作用域
作用域相关问题 下面的代码打印什么内容,为什么? // 情况 1 // 情况 2 var b = 10; var c = function b() { b = 20; console.log(b) } ...
- 成为java高手的成长历程想学好java必看
1:J2SE入门阶段(3-6个月) 学习内容:J2SE常用类,JDBC等等 动态绑定,反射机制等 2:J2EE入门阶段(3个月) 学习内容:JSP/Servlet/JavaBean MVC结构的概念 ...
- 要想深入理解mysql索引?这16个点你必须要了解!
前言 MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度. 打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQ ...
- 《Java基础知识》Java继承的概念和实现
继承时类和类之间的关系,是一个很简单很直观的概念,与显示生活中的继承(例如儿子继承了父亲财产)类似. 继承可以理解为一个类从另一个类中获取方法和属性的过程.如果类B继承于类A,那么类B就拥有类A的属性 ...
- 萌新入门Github请看这里,学不会远程教
一些废话 本文的主旨是为初次接触Github的同学提供一个入门的教程,如果你已经是Github老鸟,可以忽略本文哦,另外本文只是抛砖引玉,其实最好的教程是官方文档!!! Github官网 Github ...
- VS2019添加Link to SQL类之后,LinqDataSource配置数据源没有可选项
原创. 环境:visual studio 2019 ,.net framwork 4.0 问题: 1.新建Linq to SQL类后(.dbml文件),从服务器资源管理面板中数据库连接中,把表Mill ...
- GeoServer 2.15.0版本跨域问题解决方法
geoserver默认不开启跨域设置,开启步骤如下: 1.修改配置文件web.xml,该配置文件的路径如下 \webapps\geoserver\WEB-INF\web.xml 2.搜索:cross- ...
- RAID磁盘阵列介绍
磁盘阵列 RAID介绍 一.简介: 磁盘阵列(Redundant Arrays of Independent Drives,RAID),有“独立磁盘构成的具有冗余能力的阵列”之意. 最初是由加利福尼亚 ...