今天为大家介绍一下一下JavaScript中的预解析(变量提升)。从什么是预解析及变量的预解析和函数的预解析及加载流程进行学习(注意:我们这里说的ES5中的预解析)。
什么是解析
首先代码执行肯定需要一个执行环境,浏览器会提供一个供javaScript执行的全局作用域window。但是在javaScript执行之前会进行预解析,又称之为变量提升。预解析可以分为两部分:
- 声明(declare): var a; 简单的去理解声明就是我们声明一个变量没有赋值;
- 定义(defined):a= 100; 定义相当于给这个变量进行赋值;
在javaScript执行之前浏览器会把全局作用域下所有带有var和function关键字的进行预解析(注意是带有var和function关键字的),这也就是为什么我们学习预解析去学习变量的预解析及函数的预解析原因,变量的预解析和函数的预解析存在一定的区别如下:
- var :在预解析的时候只声明不定义
- function:在预解析的时候声明+定义都已经完成了
变量的预解析
现在有如下代码:
- console.log(a);//undefined 在代码执行之前进行预解析 只声明没有定义只是undefined
- var a = 10;
- console.log(a);//10
为了方便我们理解如图:
这也就是为什么在我们看到var a = 10;之前去输出a没有报错而是输出undefined;声明一个变量没有进行赋值那么就是undefined;
函数的预解析及加载流程
前面我们说过了函数再预解析的时候声明+定义都已经完成了,现在有如下代码:
- //定义一个函数sum
- function sum(){
- Console.log(“javascript”);
- }
- sum();//->javascript 每次调用都重新执行
- sum();//->javascript 每次调用都重新执行
- sum();//->javascript 每次调用都重新执行
我们先去看下函数的加载流程:
1. 函数在预解析的时候声明+定义都已经完成了
2. 因为函数是引用数据类型,会新开辟一个堆内存空间,将函数以字符串的形式进行存储,并且会给这堆个内存空间分配一个内存地址比如xxxfff000
3.函数的调用的时候,会开辟一个新的私有作用域,将函数体中内容从上到下依次执行
4.函数每一次调用都是相互独立的,并且函数执行完毕之后自动销毁
方便大家理解加载流程如图所示:
从上图可以分析出函数先进性了预解析,在预解析的时候声明+定义都已经完成了,并且开辟了一块堆内存空间将函数以字符串的形式进行存储,并且给这块堆内存分配一个内存地址便于我们使用的时候去找到它,因为这个时候函数以字符串的形式进行存储,也就是为什么函数定义函数不去调用是不能执行的。当我们调用的时候发现,开辟了个一个新的私有作用域,函数体从上到下去执行,并且每一次调用都会形成新的私有作用域,所以是相互独立的,并且每一个私有作用执行完毕就自动销毁了,是浏览器内置的垃圾回收机制。这样保证了性能优化。