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. NET视频教程分享

    地址:链接:https://pan.baidu.com/s/1q47WN1XFw19vLZ8XZqnB_g    提取码:8ut2  这是我收集的一套.NET学习视频教程(某智24期视频),分享出来, ...

  2. windows程序设计04_显示汉字的16进制

    看下面的代码 //utf-8编码 #include<stdio.h> int main() { char a[] = "中国"; printf("%x\n&q ...

  3. Lamada表达式小技巧介绍

    函数式编程 @FunctionalInterface interface Lf{ void dispaly(); } @FunctionalInterface为显示定义函数时编程接口,不符合函数式编程 ...

  4. css修改overflow滚动条默认样式

    html代码 <div class="inner"> <div class="innerbox"> <p style=" ...

  5. NIO Buffer 内部机理使用姿势

    关于NIO Buffer中4个重要状态属性 position.limit.capacity 与 mark Buffer本身是一个容器,称作缓冲区,里面包装了特定的一种原生类型,其子类包括ByteBuf ...

  6. CentOS7安装部署squid服务(透明代理+反向代理)

    一.squid服务介绍 Squid是一个高性能的代理缓存服务器,Squid支持FTP.gopher.HTTPS和HTTP协议.和一般的代理缓存软件不同,Squid用一个单独的.非模块化的.I/O驱动的 ...

  7. ESD选型

    通常情况ESD保护电路如下 当系统没有干扰,正常工作时,ESD器件可以忽略,几乎不起作用 当外部接口电压超过ESD器件的击穿电压(VBR),ESD器件开始起作用,并将电流分流到地. 实际ESD器件的工 ...

  8. 人生苦短,我用Python(3)

    1.对列表进行排序: (1)使用列表对象的sort()方法: 列表对象提供了sort()方法用于对原列表中的元素进行排序.排序后原列表中的元素顺序将发生改变.改变对象的sort()方法的语法格式如下: ...

  9. NodeJS4-1静态资源服务器实战_实现访问获取里面的内容

    .gitignore 匹配模式前 / 代表项目根目录 匹配模式最后加 / 代表是目录 匹配模式前加 ! 代表取反 * 代表任意一个字符 ? 匹配任意一个字符 ** 匹配多级目录 统一代码风格配置可以用 ...

  10. UWP 打开系统设置面板

    由于UWP各种权限管理的比较严格,所以在执行某一个特殊的操作之前,最好先申请一下相应的权限,以便告知用户你使用了这个权限,而且可以有效的避免App崩溃. 比如你想让用户手动打开麦克风权限,那么可以执行 ...