JS排他/同步异步问题

实现点击任何一个li标签、可以弹出对应的index值

也可以应用于没有计时器的轮播图中

在写代码的过程中,碰到了一系列的问题:

  1. 在点击li标签之后,弹出的index是最后一个索引值
  2. var 和 let 的区别

问题与代码如下:

var ali=document.getElementsByTagName("li");
for(let i=0;i<ali.length;i++)
{
   ali[i].index=i;
    ali[i].onclick = function () {
       alert(ali[i].index); //依次点击 弹出0,1,2,3,4
   }
 }
for(var j= 0;j<ali.length;j++)
{
    ali[j].index=j;
    ali[j].onclick = function () {
        /*alert(ali[j].index); */     //单写出这一句会报错
        alert(this.index);  //依次点击 弹出0,1,2,3,4
    }
}
/*
* 问题:
* 1、第一处注释处:为什么可以正确弹出0,1,2,3,4。且不需要改成alert(this.index);
* 2、第二处注释处:为什么单写这一句会报错?
* 3、第三处注释:为什么在这个for循环内必须要使用this.index,才可以弹出正确的0,1,2,3,4
* */

问题的解决

第一个问题 :就联系到了var 和 let 的区别

let:是ECMASscript 6 新增加的内容,let声明的变量只在声明的代码区块中可以使用。且不可以重复定义相同的变量。

var a;
let b;
console.log(a); //undefined
console.lig(b); //undefined
let b;//报错、不可以重复定义

在这里可以知道,在let和var声明的变量,未初始化,输出都是undefine
并且let不可以重复定义




console.log(a);//undefined
console.log(b);//ReferenceError: Cannot access 'b' before initialization

var a=10;
let b=9;

//在上面的两句console.log()被注释后
console.log(a);//10
console.log(b);//9

这段代码可以知道:

1.var声明的变量,对于JS来说会提前到整个代码的最前面,但是不会把初始值提前
2. let声明的变量,在没有被声明前输出会报错:Cannot access ‘b’ before initialization 意思是:不能在b的声明之前使用b。可知:let变量,不会被JS自动提前




var b=0;
for(let a=0;a<10;a++)
{
    b+=a;
}
console.log(a);//ReferenceError: a is not defined

//在console.log(a);被注释之后
for (var i=0;i<10;i++){
    b+=i;
}
console.log(i);//10

由这段代码可知:

  • let变量,有局部作用域。把a在for循环中封锁起来
  • var变量,全局作用域。没有区域作用域之说(除了在函数中)

现在可以解释问题1

  • 由于每一次的for循环,i的值都在不断的更新。而JS引擎内部会记住上一次循环的值。当更新时,会在上一轮的基础上更改。

  • 所以每一个ali[i].index=i; 都已经初始化了。从而可以正确的输出。

问题2 可以 和 问题3 一起解决

1、在JS 中,对于变量的声明。如果在函数内部没有找到变量的声明和定义,会是由内而外的找声明和定义。

var a=0;
function f() {
    console.log(a);
}
f();//0

//由于在函数 f 内没有找到 a 的定义,就会往外找
//发现外部有var a=0;
//从而函数内部的a就为0

所以在问题2中,由于事件函数中没有找到 j 的声明或者定义,会自动的在外层找。发现了for循环中定义了 var j = 0.然而这时,for循环已经结束,j = ali.length .很明显的会报错。因为数组的最后一个元素下标ali.length-1.所以alert(ali[j].index); 数组越界

问题3:this,只有在函数被调用的时候,才能确定this的指向。在这里this指向的就是任何一个被点击了的li标签。
this:所在的函数在那个对象中究指向这个对象。this在定时器中是特例。在事件函数中。this指向事件源。
所以可以弹出对应正确的index值

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值