今天看到闭包一道题,就是一个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);
}
});

经过验证,是可以的。

[].indexOf.call()学习的更多相关文章

  1. PyQt(Python+Qt)学习随笔:QTabWidget选项卡部件的tabBar、count、indexOf方法

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QTabWidget的每个选项卡都有一个对应的页面部件对象,可用通过count方法获取选项卡个数,可 ...

  2. Vue学习之--------列表排序(ffilter、sort、indexOf方法的使用)、Vue检测数据变化的原理(2022/7/15)

    文章目录 1.列表排序 1.1 .代码实例 1.2 .测试效果 1.3.需要掌握的前提知识 2.Vue监测数据变化的原理 2.1.代码实例 2.2 .测试效果 3.Vue检测数据的原理 3.1 基本知 ...

  3. JavaScript学习笔记:数组的indexOf()和lastindexOf()方法

    https://www.w3cplus.com/javascript/array-part-6.html

  4. 关于面试题 Array.indexof() 方法的实现及思考

    这是我在面试大公司时碰到的一个笔试题,当时自己云里雾里的胡写了一番,回头也曾思考过,最终没实现也就不了了之了. 昨天看到有网友说面试中也碰到过这个问题,我就重新思考了这个问题的实现方法. 对于想进大公 ...

  5. js数组学习整理

    原文地址:js数组学习整理 常用的js数组操作方法及原理 1.声明数组的方式 var colors = new Array();//空的数组 var colors = new Array(3); // ...

  6. jQuery-template.js学习

    花了点时间,看了下jQuery-template.js,不多废话,先上结构 jQuery.each({..},function(){}) jQuery.fn.extend({..}) jQuery.e ...

  7. 学习javascript数据结构(二)——链表

    前言 人生总是直向前行走,从不留下什么. 原文地址:学习javascript数据结构(二)--链表 博主博客地址:Damonare的个人博客 正文 链表简介 上一篇博客-学习javascript数据结 ...

  8. js学习篇1--数组

    javascript的数组可以包含各种类型的数据. 1. 数组的长度 ,直接用 length 属性; var arr=[1,2,3]; arr.length; js中,直接给数组的length赋值是会 ...

  9. Javascript数组学习

    记录下学习数组的过程 1.创建数组 var ary1 = new Array();//空数组 var ary2= [] ;//字面量 2.数组检测 //方法一 if(array instanceof ...

随机推荐

  1. java基础第五篇封装与面向对象

    a.方法: public static void main(String[] args) { } 一般定义标准: 形参:一般把 不确定的量或者变化的量定义在形参位置//圆的的半径,长方形的长和宽,传递 ...

  2. WordCount by C# 结对编程

    合作者:201631062210,201631062110 Gitee项目地址:https://gitee.com/zhouyue98/learngit 本次作业的链接地址:https://edu.c ...

  3. 关于Mac系统中my sql 和navicat for mysql 的连接问题。

    我这个完完全全的技术小小白,经过数个小时的网搜,navicat for mysql和mysql终于可以可以正常连接了,好开森啊!,我把我遇到的问题,以及解决方法记录下来,希望也可以对遇到同样问题的能够 ...

  4. java.exe is valid, but is for a machine type other than the current machine

    java.exe is valid, but is for a machine type other than the current machine jdk版本不一致问题,在32位机器上使用64位的 ...

  5. shell里的IFS内置环境变量

    IFS 的全称是 Interal Field Separator ,即“内部区域分隔符”,它也是一个内置环境变量,存储着默认的文本分隔符,默认下这分隔符是空格符(space character),制表 ...

  6. 死磕 java并发包之LongAdder源码分析

    问题 (1)java8中为什么要新增LongAdder? (2)LongAdder的实现方式? (3)LongAdder与AtomicLong的对比? 简介 LongAdder是java8中新增的原子 ...

  7. JavaScript中登录名的正则表达式及解析(0基础)

    简言 在JavaScript中,经常会用到正则表达式来进行模式匹配.例如,登录名验证,密码强度验证,字符串查找或替换等操作.现在就开始吧,零基础写出你的第一个正则表达式! 在做用户注册时,都会用到登录 ...

  8. 使用history.replaceState 修改url 不跳转

    history.replaceState(null,null,this.urlR);  //关键代码 history.replaceState是将指定的URL替换当前的URL 注意:用于替换掉的URL ...

  9. PHP超全局变量、魔术变量和魔术方法

    PHP超全局变量 $_GET 通过get方式传递的值(通过 URL 参数传递给当前脚本的变量的数组.) $_POST 通过post形式传递的值(当 HTTP POST 请求的 Content-Type ...

  10. Volley与Picasso的对比

    Volley与Picasso的对比 想写一篇文章来对比一下Volley以及Picasso,有人或许会说了,Volley和Picasso的服务对象都不同,Picasso是专注于图片的下载以及处理,而Vo ...