JS函数提升和变量提升
程序员文章站
2022-03-21 21:43:08
1.1什么是函数提升和变量的提升? JS引擎在运行整个JS代码的过程中,分为俩步。 第一步是读取和解析JS代码,第二部是执行。 在引擎解析JS代码的时候,当解析器遇见变量声明(var 变量名)和函数声明 (function 函数名)的时候,会将这些声明提到各自作用域的最前面。 1.2 作用域 在ES ......
1.1什么是函数提升和变量的提升?
js引擎在运行整个js代码的过程中,分为俩步。
第一步是读取和解析js代码,第二部是执行。
在引擎解析js代码的时候,当解析器遇见变量声明(var 变量名)和函数声明
(function 函数名)的时候,会将这些声明提到各自作用域的最前面。
1.2 作用域
在es6之前,js是没有块级作用域的。只有2种作用域:
- 1.全局作用域
- 2.函数作用域
注:在其他语言中,{...}被称为代码块,所形成的作用域被称作块级作用域,如:
if(...){ var a = 1; } for(var i = 0;i<5;i++){ var b = 1; } console.log(a); console.log(b); console.log(i);
如果以上俩例子有块级作用域的话,a,b,i是不能被访问到的,但是
在js中是可以的(es6之前),所以没有块级作用域。
2.1 变量提升
2.1.1 声明变量
首先我们声明变量是通过var关键字,如果不用var直接赋值的话会被解析器
当作是全局变量。但是切记,变量的提升只限于用var声明的变量,没通过
var声明的变量将不会被提升。看下边的例子:
var a = 1; console.log(a);// 1 // 输出的结果为1,没问题,因为代码在执行的时候是按顺序执行的。 // 解析的时候,经过变量提升后的结果如下: var a; a = 1; console.log(a);// 1
console.log(a);// undefined var a = 1; // 这次的结果输出为undefined,我们都知道,当一个变量声明了却未赋值的时候就会出现undefined, // 但是一个变量没有声明的话,就会输出 a is not defined,先看本例经变量提升后的结果: var a ; console.log(a);// undefined a = 1; // 所以由此可见,变量的提升只会提升变量的声明,而不会提升变量的赋值。
console.log(a);// a is not defined a = 1; // 当我们把var去掉的时候,结果变成了 a is not defined,很明显,没有var声明的变量,没有被提升至作用域的最前边,也就是变量提升只是对用var声明的变量而言的。
- 函数的内部也是如此
(function(){ console.log(a);//undefined var a = 1; })() 提升结果如下: (function(){ var a console.log(a);//undefined a = 1; })()
2.1.2 所以暂时我们可以总结一下变量提升:
- 只有用var声明的变量才存在变量提升这一说法
- 变量提升只提升变量的声明,不会提升赋值这一部分;
3.1 函数提升
3.1.1函数的声明
函数的声明有俩种方式,一种为:
function fn(){ } //另一种为: var fn = function(){ } // 首先的我们得知道函数属于引用类型,函数名实际上相当于一个指针,保存的是函数体所在的地址,所以函数也可以通过函数表达式var fn来声明,但是同为函数,他们的提升结果却是不同的。
3.1.2 函数式声明
function fn(){ console.log('hello'); } fn();// hello // 结果输出为hello,这个不难理解,代码的顺序执行。函数提升后的结果还是这样。
fn();// hello function fn() { console.log('hello'); } // 执行结果还是hello,因为函数在解析代码的时候,同样,函数的声明被提到了作用域的最前边,如下: function fn(){ console.log('hello'); } fn();// hello // 需要注意的是整个function fn(){...}均为函数的定义(声明)。
var fn = function(){ console.log('hello'); } fn();//hello // 用var声明的函数同变量一样,先把定义提升至最前边,如下: var fn; fn = function(){ console.log('hello'); } fn();//hello
fn();//fn is not a function var fn = function(){ console.log('hello'); } // 但是将用var声明的函数放在后边就不行了,因为这样声明的函数,提升后是下边这样的: var fn; fn();//fn is not a function fn = function(){ console.log('hello'); } // 同变量提升一样,提升的只是定义,并没有赋值。
4 综合运用
console.log(a); function a() { //定义函数 } console.log(a); var a = 3; //变量 console.log(a); 运行结果如下: function a() { } function a() { } 3
console.log(a); var a = 3; console.log(a); function a() { } console.log(a);
由此可见
俩次举例中,函数和变量是同名的,在代码未执行到变量赋值语句的时候,console打印出来的均为函数,变量赋值以后,打印的才是刚刚赋的值,所以由综合例子可以得出:
当变量和函数同名时,函数的优先级高!
总结
由以上的例子不难看出变量提升和函数提升的特点,可以总结如下:
- 所有的声明都会提升到各自作用域的最顶上去。
- 只有用var声明的变量才存在变量提升这一说法
- 变量提升只提升变量的声明,不会提升赋值这一部分;
- 同一个变量只会声明一次,其他的会被忽略掉。
- 函数声明的优先级高于变量声明的优先级
- 所有变量的声明,在函数内部第一行代码开始执行的时候就已经完成。
上一篇: 汇编原理实验 --查找子字符串的位置
下一篇: python中的模块以及包导入