javascript变量声明和作用域提升

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javascript变量声明和作用域提升相关的知识,希望对你有一定的参考价值。

以前的知识总是忘,遇到代码又看不懂。要再复习一下,顺便记录一下。

 

1   add(1,2);
2   function add(a,b){
3       alert(a+b);
4   }

 

 代码能输出3,为什么不是按顺序执行?应该是  //add is not defined ...

javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面。

也就是说,function add(a,b){alert(a+b)}是一个函数声明,告诉我们有这样一个函数,于是就被提升到作用域最前面了。同样,声明了别的变量也被提升.

上面例子就等于:

1   function add(a,b){
2       alert(a+b);
3   }
4   add(1,2);

 

注意:只是声明被提升,变量赋值或函数的表达式并没有被提升。

1 alert(a); // undefined
2 alert(b);  // undefined
3 alert(c);  // undefined
4 
5 var a=0,b=1,c=2;

 

它相当于:

1 var a,b,c
2 alert(a);
3 alert(b);
4 alert(c);
5 a=0;
6 b=1;
7 c=2;

 

函数也一样:仅仅是var=add被提升,后面的表达式还在原地。

1  (function(){
2  add(1,2); //add is not a function
3  var add = function(a,b){
4     alert(a+b)
5  }
6  })()

 

注意:即使给表达式也命名,那也不会被提升

1   (function(){
2   add(1,2);  //add is not a function
3   var add = function add(a,b){
4     alert(a+b)
5   }
6   })()

 

 

 

作用域:

1 var scope="global";  
2 function t(){  
3     console.log(scope);   //ubdefined
4     var scope="local"  
5     console.log(scope);   //local
6 }  
7 t();  

 

var scope="global";  是全局作用域,在函数里面,又定义了一个局部变量,变量提升。赋值未提升,所以是undefined,后面赋值了就是local

在C++等语言中,凡是有{}括起来的,都有块级作用域,但js没有,有函数作用域

当要调用一个对象时,它会从局部到全局,一个一个找,找到了就不继续找。

1 var name="global";  
2 if(true){  
3     var name="local";  
4     console.log(name)    //local
5 }  
6 console.log(name);    //local

 

if不是函数,没有块级作用域,它的上下文就是全局的。

相当于:

1   var name="global";  
2   var name="local";  
3   if(true){  
4         console.log(name)  
5   }  
6   console.log(name);  

 

再看这个,从局部到全局,一个一个找,找到了就不继续找。

 1 name="lwy";  
 2 function t(){  
 3     var name="tlwy";  
 4     function s(){  
 5         var name="slwy";  
 6         console.log(name);  
 7     }  
 8     function ss(){  
 9         console.log(name);  
10     }  
11     s();  //slwy
12     ss();  //tlwy
13 }  
14 t();  

 

s()先在局部找,找到了var name=‘slwy‘就输出了。

ss()在自己内部没有,就往上找,在t()函数内找,找到了var name=‘tlwy‘,也就输出了。

若没找到,就会继续在全局中找。这样就形成了一个作用域链,在最内部就是链头,没找到就沿着链找,链尾就是全局作用域了。

 

一个常见的问题,按钮,每次都是弹出最后一个:

1 var aLi = document.getElementsByTagName(‘li‘);
2 for(var i = 0; i < aLi.length; i++){
3   aLi[i].onclick = function(){
4     alert(i); // 每次都弹出最后一个的值
5   }
6 }

 

在页面加载完时,这个js函数就运行了,当我们点击时,它会去找i的值,最内部的匿名函数没有,就往上走,在外层找到了i,是4,就输出了4.

解决这方法:

1 for (var i = 0; i < aLi.length; i++) {
2     aLi[i].onclick = function (msg) {
3       show:function(){
4         alert(msg)
5 }
6 Return show;
7 })(i)
8 }
1 for (var i = 0; i < aLi.length; i++) {
2  (function(i){
3    aLi[i].onclick = function () {
4       alert(i);
5      };
6  })(i)
7 }

 

都是将他们保存起来

 

 文章用于学习记录,若有错误,望指正。

 

以上是关于javascript变量声明和作用域提升的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript之变量提升

JS预解析与变量提升

js中的函数提升和变量提升

js变量声明提升

[Effective JavaScript 笔记] 第12条:理解变量声明提升

Javascript 的变量提升与预解析