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. WSL(Windows Subsystem for Linux) Ubuntu 下byobu状态栏错误的问题

    关于WSL的,Win10 的Linux子系统如何安装,就不赘述了,Win10商店里就有,至于win7和win8.1想装这个估计也不行,所以跳过. 最近处于好奇,也懒得弄VMware的虚拟机(那玩意儿占 ...

  2. 使用iCamera 测试mt9d111 200w高分辨率摄像头小结

    使用iCamera 测试mt9d111 200w高分辨率摄像头小结 先看下产品特性 安装效果 根据前面博客的经验,该摄像头,默认配置即有输出,分辨率为800*600,yuv 于是可以写 如果使用默认配 ...

  3. OV7670 RAW输出 bayer 解码

    今天终于搞定OV7670 raw输出啦,兴奋!! 参考链接: https://pikacode.com/liplianin/s2-liplianin/commit/dab97f5d6e3b http: ...

  4. 开发 Laravel 扩展的基本流程

    创建一个空的laravel项目 composer create-project --prefer-dist laravel/laravel pkg 在新建的 laravel 项目中建立如下目录 qia ...

  5. 【Web技术】401- 在 React 中使用 Shadow DOM

    本文作者:houfeng 1. Shadow DOM 是什么 Shadow DOM 是什么?我们先来打开 Chrome 的 DevTool,并在 'Settings -> Preferences ...

  6. qrcode.js生成二维码因字符串过长而报错

    前端使用qrcode.js生成二维码的时候.有时候是会出现 qrcode length overflow (1632>1056) 目前使用的有效的解决办法是重新下载新版的qrcode.js 下载 ...

  7. 使用Gin+WebSocket在HTML中无插件播放RTSP

    在后台的开发中遇到了对接显示摄像头视频流的需求.目前获取海康及大华等主流的摄像头的视频流使用的基本都是RTSP协议.不过HTML页面并不能直接播放RTSP协议的视频流,查询了一番各种网页播放RTSP的 ...

  8. 使用for语句输出1-100之间的所有偶数

    使用for语句输出1-100之间的所有偶数 for i in range(1,101): if i%2==0: print(i) 使用while语句输出1-100之间能够被3整除的数字 j=1 whi ...

  9. 微信小程序 wepy框架 之拦截器intercepter使用

    1,在使用wepy框架创建的项目下 找到src/app.wpy 2,在app.wpy constructor方法中添加 super(); this.use('promisify');//启用ES6 p ...

  10. linux系统centos7安装最新版本nginx

    一.准备环境 1.安装centos,一般买一个阿里云测试 2.下载nginx,链接http://nginx.org/download/nginx-1.10.2.tar.gz 二.开始安装 1.cent ...