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都比较奇怪
  1. 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.预解析的更多相关文章

  1. 从var func=function 和 function func()区别谈Javascript的预解析机制

    var func=function 和 function func()在意义上没有任何不同,但其解释优先级不同:后者会先于同一语句级的其他语句. 即: { var k = xx(); function ...

  2. javaScript中的小细节-script标签中的预解析

    首先介绍预解析,虽然预解析字面意思很好理解,但是却是出坑出的最多的地方,也是bug经常会有的地方,利用好预解析的特性可以解决很多问题,并且提高代码的质量及数量,浏览器在解析代码前会把变量的声明和函数( ...

  3. JavaScript函数之作用域 / 作用链域 / 预解析

    关于作用域和作用链域的问题,很多文章讲的都很详细,本文属于摘录自己觉得对自己有价值的部分,留由后用,仅供参考,需要查看详细信息请点击我给出的原文链接查看原文件 做一个有爱的搬运工~~ -------- ...

  4. JavaScript的变量预解析特性

    JavaScript是解释型语言是毋庸置疑的,但它是不是仅在运行时自上往下一句一句地解析的呢?事实上或某种现象证明并不是这样的,通过<JavaScript权威指南>及网上相关资料了解到,J ...

  5. js的预解析

    在ES6之前,变量使用var声明,会存在变量的预解析(函数也有预解析).ES6引了let和const,但是现阶段ES6并没有完全普及,而且很多比较老的代码都还是按照ES5的标准甚至是ES3的标准来书写 ...

  6. js 预解析

    前言 JavaScript是解释型语言是毋庸置疑的,但它是不是仅在运行时自上往下一句一句地解析的呢? 事实上或某种现象证明并不是这样的,通过<JavaScript权威指南>及网上相关资料了 ...

  7. javascript解析机制——预解析

    JavaScript解析机制是什么? JavaScript解析过程分为两个阶段,一个是编译阶段,另外一个就是执行阶段. * 编译阶段         编译阶段就是我们常说的JavaScript预解析( ...

  8. javascript的执行和预解析

    很久以前遇到过一个面试题目,的的确确是面试官问我的问题,下面是这个问题的代码部分.由于年少无知,没有回答上,被无情pass了. var u ='hello world'; ;(function(){ ...

  9. javascript预解析和作用域

    JavaScript解析过程分为两个阶段: 一是:编译阶段.就是JavaScrip预解析阶段,在这个阶段JavaScript解析器将完成把JavaScript脚本代码转换到字节码; 二是:执行阶段.在 ...

  10. Javascript预解析、作用域、作用域链

    最近在看js的一些资料,总结一下昨晚看到的js作用域方面的知识,不准确的地方希望留言指正! 先看片段js代码如下: < script type="text/javascript&quo ...

随机推荐

  1. 【CSS】271- RGB、HSL、Hex网页色彩,看完这篇全懂了

    作者:CSS可乐 http://csscoke.com/2015/01/01/rgb-hsl-hex/ 网页使用到的色彩标示方法中,从古早时期大家都在用的16进位码(#000000).RGB色值标示. ...

  2. leetcode-164、最大间距

    export default (arr) => { // 如果数组长度小于2返回0 if (arr.length < 2) { return 0 } // 排序 arr.sort() // ...

  3. 1. 初探--prometheus调研

    一.基本概念 Prometheus 是由前 Google 工程师从 2012 年开始在 Soundcloud 以开源软件的形式进行研发的系统监控和告警工具包,自此以后,许多公司和组织都采用了 Prom ...

  4. CCF-CSP题解 201803-3 URL映射

    题目要求写一个简易的URL规则和URL地址匹配的程序. 说说我的思路. 将URL规则和地址都截成片段用结构体\(<type, str[]>\)存储.对于URL规则,\(type\)为0代表 ...

  5. 《Java基础知识》Java锁详解(volatile,synchronized等)

    volatile: 让变量每次在使用的时候,都从主存中取. volatile具有synchronized关键字的“可见性”,但是没有synchronized关键字的“并发正确性”,也就是说不保证线程执 ...

  6. Supermap/Cesium 开发心得----获取三维视角的四至范围

    网上目前有两种获取当前Camera的四至范围的方法 方法一    这种方法是最通用的,即使在哥伦布视角(2.5D下依旧能准确获取值) function getCurrentExtent() { // ...

  7. Python 的 Geth 封装库 PyGeth

    PyGeth 是一个 Python 封装库,用来作为子进程运行 geth. 系统依赖 该库需要 geth 可执行文件. 安装 pip install py-geth 快速启动 运行连接到 mainne ...

  8. vue组件常用声明方式

    一.前言 这是自己重新写的一个,感觉以前的太写了很多不必要的方式 实际当中基本不会用的 所以自己写了一个常用的组件什么方式 更加的通俗易懂 二.代码如下 <!DOCTYPE html> & ...

  9. 使用系统定时器SysTick实现精确延时微秒和毫秒函数

    SysTick定时器简介 SysTick定时器是存在于系统内核的一个滴答定时器,只要是ARM Cortex-M0/M3/M4/M7内核的MCU都包含这个定时器,它是一个24位的递减定时器,当计数到 0 ...

  10. asp.net core的AOP记录

    序曲:学习编程最好的方式就是敲代码,没有比这个更好的方法,哪怕你看了上百G的视频,都不如你自己敲几行代码更为有效.还有要记得敲完代码然后写一篇随笔来记录一下你所学所想. 什么叫AOP? AOP面向切面 ...