[].indexOf.call()学习

今天看到闭包一道题,就是一个li列表,点击列表控制台输出对应的索引。这里考察了var的作用域问题和闭包对外部变量的引用问题,有几种解决方法。

html:
<ul>
  <li>test1</li>
  <li>test2</li>
  <li>test3</li>
  <li>test4</li>
  <li>test5</li>
  <li>test6</li>
  <li>test7</li>
  <li>test8</li>
  <li>test9</li>
  <li>test10</li>
</ul>


js:
var ul = document.querySelector('ul');
var lis = document.querySelectorAll('ul li');

// 法一:使用es6的let代替var
for (let k = 0; k < lis.length; k++) {
  lis[k].addEventListener('click',function(){
    console.log('法一:',k)
  })
}

// 法二:使用闭包解决
for (var m = 0; m < lis.length; m++) {
  (function(m){
    lis[m].addEventListener('click',function(){
      console.log('法二:',m)
    },false)
  })(m)
}

// 法三:事件委托
ul.addEventListener('click', function(e){
  var target = e.target;
  if (target.nodeName.toLowerCase() === 'li') {
    console.log('法三:',[].indexOf.call(lis,target))
  }
},false)

其中法三是我借鉴别人的。它里面的[].indexOf.call()引起我的注意,因为我一开始没看到这是什么意思,感觉好高级啊(捂脸)。于是查了call的用法。

call()

语法:call([thisObject[,arg1 [,arg2 [,...,argn]]]]);,应用某一对象的一个方法,用另一个对象替换当前对象。
可以指定上下文this;可以使用call()来实现继承:写一个方法,然后让另外一个新的对象来继承它(而不是在新对象中再写一次这个方法)。

示例:

指定上下文:
function say(){
  console.log('my name is : ' + this.name);
}
var obj = {
  name: 'cat'
}
say.call(obj) // "my name is : cat"

实现继承
function Animal(name,color){
  this.name = name;
  this.color = color;
  this.say = function(){
    console.log('My name is '+this.name+', and my color '+ this.color)
  }
}
function Cat(name,color){   
    Animal.call(this,name,color)
}
var cat = new Cat('cat','black')
cat.color  // "black"
cat.say()  // My name iscat, and my color:black

注意:
另外apply()的功能和call一样,只是传参的方式不同。apply的第二个参数是一个数组.

回到开头的[].indexOf.call(),根据上面call用法的分析,这里是想指定上下文。数组的indexOf(string)是返回字符串string在父串中首次出现的位置,从0开始,-1表示没有。
类似拓展:
[].join.call([1,2,3],',') // "1,2,3"
[].sort.call([5,7,1,3,4]); // [1, 3, 4, 5, 7]

那根据这个拓展,开头闭包的题目是不是可以直接使用这个call呢?

[].forEach.call(lis, function (item, index) {
  item.onclick = function () {
    console.log('法四:',index);
  }
});

经过验证,是可以的。

转载于:https://www.cnblogs.com/MJyaaatou/p/9540539.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值