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 }

都是将他们保存起来

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

时间: 2024-08-02 06:52:58

javascript变量声明和作用域提升的相关文章

【转】javascript变量声明 及作用域

javascript变量声明提升(hoisting) javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面. 先看一段代码 1 2 3 4 5 var v = "hello"; (function(){   console.log(v);   var v = "world"; })(); 这段代码运行的结果是什么呢?答案是:undefined这段代码说明了两个问题,第一,funct

javascript变量声明 及作用域

javascript变量声明提升(hoisting) http://openwares.net/js/javascript_declaration_hoisting.html 可能要FQ一下 javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面. 先看一段代码 1 2 3 4 5 var v = "hello"; (function(){   console.log(v);   var v = &qu

JavaScript 变量声明提升

JavaScript 变量声明提升 一.变量提升的部分只是变量的声明,赋值语句和可执行的代码逻辑还保持在原地不动 二.在基本的语句(或者说代码块)中(比如:if语句.for语句.while语句.switch语句.for...in语句等),不存在变量声明提升 三.函数声明会提升,但是函数表达式的函数体就不会提升 1 fun(); // hello 2 function fun(){ 3 console.log("hello"); 4 } 5 // -------------- 6 //

javascript变量声明提升

javascript变量声明提升(hoisting) javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面. 先看一段代码 1 2 3 4 5 var v = "hello"; (function(){   console.log(v);   var v = "world"; })(); 这段代码运行的结果是什么呢?答案是:undefined这段代码说明了两个问题,第一,funct

javascript变量声明前置

变量声明前置: 所谓的变量声明前置就是在一个作用域块中,所有的变量都被放在块的开始出声明,下面举个例子你就能明白了 1 var a = 1; 2 function main() { 3 console.log(a);//1 4 } 5 main();//输出1 上面代码输出的是外层变量a的值 1 var a = 1; 2 function main() { 3 console.log(a); 4 var a = 2; 5 } 6 main()//输出undefined 问什么这样就输出undef

Javascript变量声明

Javascript变量声明 JavaScript中即可以使用双引号声明字符串,也可以使用单引号声明字符串.主要是为了方便和html集成,避免转义符的麻烦. JavaScript是动态类型,因此 var i=10;i='test'是合法的. var m,n,x,y=10;也是合法 判断变量是否可用 Javascript中,要用到一个变量计算的时候,首先要判断变量不是undefined也不是null 有两种判断方法,但是有区别,推荐第二种. 第一种: <script type="text/j

javascript变量声明提升(hoisting)

javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面. 先看一段代码 1 2 3 4 5 var v = "hello"; (function(){   console.log(v);   var v = "world"; })(); 这段代码运行的结果是什么呢? 答案是:undefined 这段代码说明了两个问题, 第一,function作用域里的变量v遮盖了上层作用域变量v.代

javascript变量声明,hoisting机制,面向对象

以下不遵守可能引起未知错误 1.  表示区块起首的花括号,不要另起一行. 2.  不要省略句末的分号 3.  不要使用with语句,可以减少代码的书写,但是会造成混淆. 4.  不要使用"相等"(==)运算符,只使用"严格相等"(===)运算符. == 两边值类型不同的时候,要先进行类型转换,再比较,造成很多意想不到的情况. === 不做类型转换,类型不同的一定不等. 0 == ''// true 1 == true // true 2 == true // fal

javascript变量声明的一点感想

相对于C/C++来说,ECMAScript里的for循环并不能创建一个局部的上下文. for (var k in {a: 1, b: 2}) { alert(k); } alert(k); // 尽管循环已经结束但变量k依然在当前作用域 任何时候,变量只能通过使用var关键字才能声明. 上面的赋值语句: a = 10; 这仅仅是给全局对象创建了一个新属性(但它不是变量).“不是变量”并不是说它不能被改变,而是指它不符合ECMAScript规范中的变量概念,所以它“不是变量”(它之所以能成为全局对