博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JavaScript的变量及函数声明提升及预解析
阅读量:4599 次
发布时间:2019-06-09

本文共 2011 字,大约阅读时间需要 6 分钟。

JavaScript引擎在执行的时候,会在相应代码段寻找var声明的变量及函数声明(函数表达式不会提升),把所有变量和函数的声明都提升到当前作用域的最前面。此时变量是未赋值的(undefined),当执行到相应代码段才会赋值,函数是其本身。

并且有以下一些坑:

1.变量声明及函数声明预解析时,变量解析为undefined,函数解析为其本身。预解析时函数声明优先级高于变量声明,函数声明会覆盖变量声明,但不会覆盖变量赋值。如果声明变量的同时初始化或赋值那么变量优先级高于函数。

例1:预解析时,变量解析为undefined,函数解析为其本身,函数声明会覆盖变量声明,故1行输出如下结果。变量赋值覆盖函数,故6.7行结果如下。

1 console.log(a);     // function a(){console.log(2);  }2 var a = 1;3 function a(){4     console.log(2);    5  }6  console.log(a);    //17  a();    //无法执行

例2:变量a预解析为undefined。fn1运行时沿着作用域链找到8行变量a,但该a在fn1后面故没有赋值,输出undefined。fn同样找到相同未赋值的变量a,输出undefined。

11行根据作用域链输出的是全局变量a。

1 var a =1; 2 function fn(){ 3    console.log(a); 4    function fn1(){ 5        console.log(a); 6     } 7     fn1(); 8     var a =2; 9 }10 fn();    //undefined    undefined11 console.log(a);    //1

2.没有使用var声明的变量为全局变量,预解析时没有使用var声明的同名变量会被隐藏。

例:预解析时8行变量a声明隐藏,fn1及fn运行时沿着作用域链找到全局变量a声明。并且在8行时全局变量a重新赋值。

1 var a =1; 2 function fn(){ 3    console.log(a); 4     function fn1(){ 5         console.log(a); 6      } 7      fn1(); 8      a =2; 9  }10  fn();    //1  111  console.log(a);    //2

3.函数形参相当于变量声明。

例:函数fn的形参相当于变量声明var a ,预解析为undefined,故7行运行时沿作用域链找到未赋值的变量a。

1 var a = 1;2 function fn(a){3   alert(5);4   alert(a);5 6 }7 fn();    // 5   undefined8 alert(a);    //19 fn(a);    //5    1

4.仅仅声明某一个函数,引擎并不会对函数内部的任何变量进行查找或赋值操作。只会对函数内部的语法错误进行检查。

所以循环语句的声明:

1 for(var i=0; i<10; i++) {2     result[i] = function(){3       return i;4   }   }

 我原本以为它是这样的:

1 result[0] = function() { return 0;};2 result[1] = function() { return 1;};3 result[2] = function() { return 2;};4 ......

 实际上它是这样的:

1 result[0] = function() { return i;};2 result[1] = function() { return i;};3 result[2] = function() { return i;};4 ......

故下例:

1 function createFunctions() { 2     var result = newArray(); 3     for(var i=0; i<10; i++) { 4         result [i] = function() { 5             return i; 6          } 7      } 8     return result; 9 }10 var foo = createFunctions();11 console.log(foo[0]());    //10

 

转载于:https://www.cnblogs.com/kongzheng0102/p/6291398.html

你可能感兴趣的文章
C#实现动态页面静态化
查看>>
可选参数、命名参数、.NET的特殊类型、特性
查看>>
利用CGLib实现动态代理实现Spring的AOP
查看>>
面试之SQL(1)--选出选课数量>=2的学号
查看>>
Minimum Window Substring
查看>>
IIS处理并发请求时出现的问题
查看>>
数学作业
查看>>
使用pycharm开发web——django2.1.5(二)创建一个app并做一些配置
查看>>
[ZPG TEST 105] 扑克游戏【Huffman】
查看>>
_bzoj2005 [Noi2010]能量采集
查看>>
pat 团体天梯赛 L3-010. 是否完全二叉搜索树
查看>>
烟草MES系统介绍-序
查看>>
优先队列小结
查看>>
线程安全与可重入函数之间的区别与联系
查看>>
bat批处理中如何获取前一天日期
查看>>
{Nodejs} request URL 中文乱码
查看>>
异常及日志使用与项目打包
查看>>
努力,时间,坚持,自律
查看>>
真三 bug PT的凤凰
查看>>
???动态SQL
查看>>