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 ...
随机推荐
- 【CSS】271- RGB、HSL、Hex网页色彩,看完这篇全懂了
作者:CSS可乐 http://csscoke.com/2015/01/01/rgb-hsl-hex/ 网页使用到的色彩标示方法中,从古早时期大家都在用的16进位码(#000000).RGB色值标示. ...
- leetcode-164、最大间距
export default (arr) => { // 如果数组长度小于2返回0 if (arr.length < 2) { return 0 } // 排序 arr.sort() // ...
- 1. 初探--prometheus调研
一.基本概念 Prometheus 是由前 Google 工程师从 2012 年开始在 Soundcloud 以开源软件的形式进行研发的系统监控和告警工具包,自此以后,许多公司和组织都采用了 Prom ...
- CCF-CSP题解 201803-3 URL映射
题目要求写一个简易的URL规则和URL地址匹配的程序. 说说我的思路. 将URL规则和地址都截成片段用结构体\(<type, str[]>\)存储.对于URL规则,\(type\)为0代表 ...
- 《Java基础知识》Java锁详解(volatile,synchronized等)
volatile: 让变量每次在使用的时候,都从主存中取. volatile具有synchronized关键字的“可见性”,但是没有synchronized关键字的“并发正确性”,也就是说不保证线程执 ...
- Supermap/Cesium 开发心得----获取三维视角的四至范围
网上目前有两种获取当前Camera的四至范围的方法 方法一 这种方法是最通用的,即使在哥伦布视角(2.5D下依旧能准确获取值) function getCurrentExtent() { // ...
- Python 的 Geth 封装库 PyGeth
PyGeth 是一个 Python 封装库,用来作为子进程运行 geth. 系统依赖 该库需要 geth 可执行文件. 安装 pip install py-geth 快速启动 运行连接到 mainne ...
- vue组件常用声明方式
一.前言 这是自己重新写的一个,感觉以前的太写了很多不必要的方式 实际当中基本不会用的 所以自己写了一个常用的组件什么方式 更加的通俗易懂 二.代码如下 <!DOCTYPE html> & ...
- 使用系统定时器SysTick实现精确延时微秒和毫秒函数
SysTick定时器简介 SysTick定时器是存在于系统内核的一个滴答定时器,只要是ARM Cortex-M0/M3/M4/M7内核的MCU都包含这个定时器,它是一个24位的递减定时器,当计数到 0 ...
- asp.net core的AOP记录
序曲:学习编程最好的方式就是敲代码,没有比这个更好的方法,哪怕你看了上百G的视频,都不如你自己敲几行代码更为有效.还有要记得敲完代码然后写一篇随笔来记录一下你所学所想. 什么叫AOP? AOP面向切面 ...