作用域问题


1.下面这段javascript代码,

1
2
3
4
5
6
var msg= 'hello' ;
for (var i=0; i<10; i++)
{
     var msg= 'hello' +i*2+i;
}
alert(msg);

最后一句alert的输出结果是? //hello189

javascript只有函数域,没有块作用域的概念,所以在同一个作用域中同一个变量声明多次还是第一次声明那个!(所以for循环不会形成作用域)

编译器在解析的时候,会发现声明了两个变量,但是后面的那个发现前面的已经声明了所以被忽略(忽略的是后面的声明,会进行重新赋值而已)。所以for循环中的msg的声明其实是无效的,从头至尾都是在操作同一个msg。

而for循环里面的var msg='hello'+i*2+i;只是相当于再次赋值操作而已。

var a=5;
var b=10;
if(a===5){
      let a=4;//the scope is inside the if-block
      var b=1;//the scope is inside the function
      console.log(a);//4
      console.log(b);//1
   }
console.log(a);//5
console.log(b);//1
--------------------

var a=5;
function foo(){
var a=10;
console.log(a);
}
foo();//10
console.log(a);//5

--------------------
var a=5;
function foo(){
a=10;
console.log(a);
}
foo();//10
console.log(a);//10

if和for没有块作用域,函数有函数作用域。

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

2.现有如下html结构

1
2
3
4
5
6
<ul>
  <li>click me</li>
  <li>click me</li>
  <li>click me</li>
  <li>click me</li>
</ul>

运行如下代码:

1
2
3
4
5
6
7
function creatFunction () {
    var elements=document.getElementsByTagName( 'li' );
     var length=elements.length;
     for (var i= 0 ;i<length;i++){
         elements[i].onclick=function(){
                alert(i);
     }
  }
}

依次点击4个li标签,哪一个选项是正确的运行结果()? //依次弹出4,4,4,4

每个li标签的onclick事件执行时,本身onclick绑定的function的作用域中没有变量i,i为undefined,则解析引擎会寻找父级作用域,发现父级作用域中有i,且for循环绑定事件结束后,i已经赋值为4,所以每个li标签的onclick事件执行时,alert的都是父作用域中的i,也就是4。这是作用域的问题。

解答:这里的事件,绑定的并非是i的值,而是i本身(alert里的i),所以当程序执行完,i的值变为4,去执行onclick事件时,执行alert(i) ,自动查找i,值为4,所以依次弹出4。

改正:
1
2
3
4
5
6
7
8
9
10
function creatFunction (){
   var elements=document.getElementsByTagName( 'li');
     var length=elements.length;
     var handler = function(i){
         return fucntion(){
             alert(i);
         }
     }
     for(var i=0;i<length;i++){
         elements[i].onclick= handler(i);
  }
}
避免在循环中创建函数,可以在循环之外创建一个辅助函数,让这个辅助函数返回一个绑定了当前i值得函数,避免混淆
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
3.
if (!  "a" in window){
     var a =  1 ;
}
alert(a);
请问 a 的结果是什么? //undefined
javascript只有函数作用域, 没有块作用域,即if,for等语句里声明的变量和其外一层的变量的作用域是一样的(函数作用域,作用域的“局部"是相对于函数而言的)。
使用var声明的变量会被自动添加到最接近的环境的顶部(即全局作用环境中); 变量提升仅提升变量声明,而不是变量赋值。
变量提前问题,等价于:
1
2
3
4
5
var a;
if (! "a" in window){
     a = 1 ;
}
alert(a);

这题还有一个细节 ,在代码的顶部var声明的变量会被认为是window的属性,如果在代码中直接使用a= 1 ,变量同样会被认为是全局变量但是并不是window的属性。
1
2
3
4
5
6
7
if (!  "a" in window){
     a = 1;
}
 
alert(a);
这样的话会弹出1,相当于没有了变量声明这一步,if语句就会执行。
 

转载于:https://www.cnblogs.com/aixiuxiu/p/6538059.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值