今天看到闭包一道题,就是一个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. IBM Websphere MQ常用命令及常见错误

    MQSC: MQ Script Command  (不区分大小写) 注明: 下面命令行中的队列管理器名字,队列名字分别用QmgrName, QName替代. 下面标蓝色的,都需要根据实际配置更改! 打 ...

  2. 使用JS判断客户端、浏览器、操作系统类型

    一.JS判断客户端类型 JS判断客户端是否是iOS或者Android手机移动端 通过判断浏览器的userAgent,用正则来判断手机是否是ios和Android客户端. 核心代码如下: 方法一: &l ...

  3. mysql实现rownum方法

    1.语句:SELECT @rownum:=@rownum+1 AS rownum, Orderstate.* FROM (SELECT @rownum:=0) r, Orderstate ; 执行结果 ...

  4. redis之安装

    redis之安装 redis redis介绍 redis是一个key-value存储系统,菲关系型数据库.和Memcached类似,他支持存储的value类型相对更多,包括字符串.列表.哈希散列表.集 ...

  5. (转)磁盘阵列RAID原理、种类及性能优缺点对比

    磁盘阵列RAID原理.种类及性能优缺点对比 原文:http://www.cnblogs.com/chuncn/p/6008173.html 磁盘阵列(Redundant Arrays of Indep ...

  6. 《从0到1学习Flink》—— Data Source 介绍

    前言 Data Sources 是什么呢?就字面意思其实就可以知道:数据来源. Flink 做为一款流式计算框架,它可用来做批处理,即处理静态的数据集.历史的数据集:也可以用来做流处理,即实时的处理些 ...

  7. java中循环的不同终止方式

    1.break:直接强行跳出当前循环,不再执行剩余代码.但在多重循环的情况下,若break在内层循环中,则仅仅终止了内层循环,外循环照常执行. 2.continue:仅仅终止此次循环. 3.retur ...

  8. Android笔记--Bitmap(二)内存管理

    Bitmap(二) 内存管理 1.使用内存缓存保证流畅性 这种使用方式在ListView等这种滚动条的展示方式中使用最为广泛, 使用内存缓存 内存缓存位图可以提供最快的展示.但代价就是占用一定的内存空 ...

  9. java控制远程ssh-JSCH(二)

    github: https://github.com/wengyingjian/ssh-java-demo.git 这次找到了一套新的api,叫jsch.网上查了一下,顺便把官网的几个demo给一通拿 ...

  10. windows 密钥

    server 2016数据中心CB7KF-BWN84-R7R2Y-793K2-8XDDG