文档章节

js预解析

风中一匹哈士奇
 风中一匹哈士奇
发布于 2017/08/31 23:14
字数 1351
阅读 4
收藏 0

 

首先看一下什么是预解析:

预解析:在当前作用域下,js运行之前,会把带有var和function关键字的事先声明,并在内存中安排好。然后再从上到下执行js语句。

预解析只会发生在通过var定义的变量和function上。

全局作用域其实是全局对象的作用域,任意地方都可以访问到(如果没有被函数作用域覆盖)。函数作用域则是整个函数范围,不论它是在函数的什么位置声明的!

作用域的嵌套

当一个块或者一个函数嵌套再另外一个块或者函数中,就发生了作用域的嵌套,因此,在当前的作用于中无法找到某个变量的时候,引擎就会在上一级的作用域中继续查找,直到找到(全局)这个变量为止,如果在全局作用域中找不到这个变量,就会报错。

不过,在ES6中,新增了一个块级作用域,

在es5中没有块的概念,在es6中才有

Eg:

for(var i = 0;i<arr.length;i++){

let a = 2;

console.log(a);

}

这个for循环花括号内就是个块,其内部声明的变量是局部变量,而不像es5中为全局变量。

这里说明一点,就是let声明的变量必须在调用之前,否则会报ReferenceError异常

eg:

function f(){

    console.log(a);

    let a="hello";

}

f();            //这里a虽然被提升,但却报了引用错误(ReferenceError)

 

这里还引申出一个东西,就是词法作用域   

词法作用域就是在写代码的时候,将变量和作用域写在哪里来决定的,也就是代码在编写的过程中,体现出来的作用范围,代码一旦写好了,作用域的范围就已经确定好了,记住下面几条规则

词法作用域的规则:

1、函数允许访问函数外的数据

2、整个代码结构中只有函数可以限定作用域

3、作用域的规则首先要使用提升(函数声明提升和变量声明提升)规则

4、如果当前作用域中有一个变量,就不考虑外面的同名变量

接着开始咱们正题

首先:

一、1变量声明:

var x;  //变量声明

var x=10;  //变量声明并赋值

x=10;  //定义全局变量并赋值

2函数声明

function fn(){}  //函数声明并定义,这个叫做函数声明

var fn=function(){};  //这个叫做函数表达式,实际上定义了一个局部变量fn和一个匿名函数,然后把这个匿名函数赋值给了fn

至于优先级,函数声明>函数表达式,在js解析的时候,函数声明会提到最顶端,最先解析。

二. 变量提升

举个栗子:

var a=2;

    function f(){

        console.log(a);

        if(true){

            var a="hello";

        }

    }

f();

这里其实打印出来的应该是undefined。

如果说这段代码被翻译成这样,能看明白吗?

    function f(){   //函数声明,放上面

        var a;      //定义,但是没有赋值

        console.log(a);   //undefined

        if(false){

            var a="hello";

        }

}

var a;

    a = 2;

f();

这样是不是就一目了然了,这里要说的就是,变量提升,只提升声明,不提升赋值,当声明过,但是没有赋值的a打印的时候,a为undefined。

 

三、重复声明

但是如果我再声明变量的时候不小心重复声明了怎么办,会出现什么情况,这就是变量重复声明:看栗子

var a=1;

console.log(a);

if(true){

    var a=2;

    console.log(a);

}

console.log(a);  //这里结果输出的是 1 2 2

虽然看起来a申明了两次,但上面说了,js的var变量只有全局作用域和函数作用域两种,并且申明会被提升,因此实际上a只会在最顶上开始的地方申明一次,var a=2的申明会被忽略,仅用于赋值。翻译过来就是

Var a;

Var a;   //重复声明则被忽略

a=1;

console.log(a); //1

If(true){

a = 2;

console.log(a);   //2

}

console.log(a);   //2   这里a被重新赋值,所以为2;

 

四、那如果变量和函数声明同时提升呢?

下面对比两个栗子

栗子一:console.log(foo);

function foo(){};

var foo="I am text";

 

栗子二:console.log(foo);

var foo=function(){};

var foo="I am text";

 

他们分别打印什么呢?

第一个:打印出来function foo(){}       第二个打印 undefined

为啥呢?这就是说第一点的时候提到的优先级,函数声明会提到最上面,

1、函数声明被提升到最顶上;

2、申明只进行一次,因此后面var foo='i am text'的声明会被忽略。

第一个:

function foo(){};

Var foo ;

console.log(foo);

foo="I am text";

第二个:

var foo ;

var foo;

console.log(foo);

foo=function(){};

foo="I am text";

所以才会出现以上结果。

 

Js预解析总结

1、所有声明都会被提升到作用域的最顶上

2、同一个变量申明只进行一次,并且因此其他声明都会被忽略

3、函数声明的优先级优于变量申明,且函数声明会连带定义一起被提升

 

这篇文章是参考了一些文章,以及自己的一些体会写的,有不足的地方请指出,谢谢!

© 著作权归作者所有

共有 人打赏支持
风中一匹哈士奇
粉丝 4
博文 8
码字总数 7492
作品 0
昌平
程序员
JavaScript 为什么快--第二篇

上一篇,我们介绍了 V8 引擎的执行管道架构。本篇将着重介绍 V8 的语法解析过程。原视频 上一篇是产品经理思维;本篇则是理工科思维; 语法解析阶段对于前端来说尤其重要,相对 Noder 来说较...

秦粤
08/10
0
0
第112天:javascript中函数预解析和执行阶段

关于javascript中的函数:   1、预解析:把所有的函数定义提前,所有的变量声明提前,变量的赋值不提前   2、执行 :从上到下执行,但有例外(setTimeout,setInterval,ajax中的回调函数,...

半指温柔乐
2017/12/12
0
0
深入浅出JS - 变量提升(函数声明提升)

前言 在我们的日常工作中,变量无处不在。更加深入的去了解它,能够使得自己的JS水平更上一层楼, 从变量提升这个小知识点着手,让我们一起来深入了解JS吧! 变量提升的小栗子 分析原因 JS引...

秋秋秋丷
05/17
0
0
高性能JavaScript模板引擎原理解析

本文将用最简单的示例代码描述现有的 javascript 模板引擎的原理,包括新一代 javascript 模板引擎 artTemplate 的特性实现原理,欢迎共同探讨。 artTemplate 介绍 artTemplate 是新一代 ja...

李朝强
2013/07/29
0
0
JSON,异步加载(学习笔记)

JSON是一种传输数据的格式(以对象为样板,本质上就是对象,但用途有区别,对象就是本地用的,json是用来数据传输的,前端与后端的数据通信) JSON是静态类(不需要构造),类似于Math,内部...

Mrs_CoCo
04/23
0
0

没有更多内容

加载失败,请刷新页面

加载更多

arts-week10

Algorithm 905. Sort Array By Parity - LeetCode Review Who’s Afraid of the Big Bad Preloader? 一文读懂前端缓存 一个网络请求3个步骤:请求,处理,响应,而前端缓存主要在请求处响应这两步...

yysue
今天
4
0
00.编译OpenJDK-8u40的整个过程

前言 历经2天的折腾总算把OpenJDK给编译成功了,要说为啥搞这个,还得从面试说起,最近出去面试经常被问到JVM的相关东西,总感觉自己以前学的太浅薄,所以回来就打算深入学习,目标把《深入理...

凌晨一点
今天
5
0
python: 一些关于元组的碎碎念

初始化元组的时候,尤其是元组里面只有一个元素的时候,会出现一些很蛋疼的情况: def checkContentAndType(obj): print(obj) print(type(obj))if __name__=="__main__": tu...

Oh_really
昨天
6
2
jvm crash分析工具

介绍一款非常好用的jvm crash分析工具,当jvm挂掉时,会产生hs_err_pid.log。里面记录了jvm当时的运行状态以及错误信息,但是内容量比较庞大,不好分析。所以我们要借助工具来帮我们。 Cras...

xpbob
昨天
162
0
Qt编写自定义控件属性设计器

以前做.NET开发中,.NET直接就集成了属性设计器,VS不愧是宇宙第一IDE,你能够想到的都给你封装好了,用起来不要太爽!因为项目需要自从全面转Qt开发已经6年有余,在工业控制领域,有一些应用...

飞扬青云
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部