今天看到闭包一道题,就是一个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. SpringBoot进阶教程(五十九)整合Codis

    上一篇博文<详解Codis安装与部署>中,详细介绍了codis的安装与部署,这篇文章主要介绍介绍springboot整合codis.如果之前看过<SpringBoot进阶教程(五十二 ...

  2. VxWorks实验八 信号

    实验八信号1 实验目的1.学习使用信号2 实验内容在实验一建立的 project 中,编写一段信号处理程序,将其与SIGINT 相关连,使用kill()发送SIGINT 信号并调用信号处理程序.观察运 ...

  3. Ionic中基于js的扩展(指令和服务)来实现各种效果

    1.ion-header-bar ion-footer-bar ion-content align-title='left/ritght/center <body> <ion-hea ...

  4. Java EE学习笔记(十)

    MyBatis与Spring的整合 1.整合环境搭建 1).要实现MyBatis与Spring的整合,很明显需要这两个框架的JAR包,但是只使用这两个框架中所提供的JAR包是不够的,还需要其他的JAR ...

  5. Linux unzip用法

    1.把文件解压到当前目录下 unzip test.zip 2.如果要把文件解压到指定的目录下,需要用到-d参数. unzip -d /temp test.zip 3.解压的时候,有时候不想覆盖已经存在 ...

  6. 学习 primer 第8章 IO库 小结

    iostream处理控制台IO fstream处理命名文件IO stringstream完成内存string的IO 非常重要!!!!!!!!!!  ========================== ...

  7. Ubuntu 下修改Tomcat和Jetty默认的JDK和初始内存

    修改/etc/default/tomcat  或者  /etc/default/jetty   文件 中的 JAVA_HOME 和 JAVA_OPTS

  8. Spring Boot自动配置原理与实践(一)

    前言 Spring Boot众所周知是为了简化Spring的配置,省去XML的复杂化配置(虽然Spring官方推荐也使用Java配置)采用Java+Annotation方式配置.如下几个问题是我刚开始 ...

  9. Java基础:(二)String字符串

    一.String概述 String被声明为final,因为它不可被继承. 内部使用char数组存储数据,该数组被声明为final,这意味着value数组初始化之后就不能再引用其他数组.并且String ...

  10. JS和jquery获取各种屏幕的宽度和高度的代码

    Javascript: 网页可见区域宽: document.body.clientWidth 网页可见区域高: document.body.clientHeight 网页可见区域宽: document ...