JS的splice()方法在for循环中使用可能会遇到的坑
在写JS代码时,我们常常使用 splice 函数来删除数组中的元素,因为 splice 函数会直接对数组进行修改,从而不需再自己写一个算法来移动数组中的其他元素填补到被删除的位置。splice 功能十分强大,除了可以删除数组的元素之外,还可以删除的同时添加新的元素到删除的位置等等用法。在本篇文章中,我只介绍 splice 的删除数组元素的用法,和在 for 循环中使用 splice 时遇到过的坑,作为记录以免我下次忘记了这个坑。
在使用 splice 之前,必备条件是,要先有一个数组。。。
var arr = new Array(1, 2, 3, 4, 5); //初始化一个数组 [ 1, 2, 3, 4, 5 ]
看到这个数组,我觉得中间的数字3不好看,我要把它删掉。数字3是数组下标2的元素,而且我只需要删掉1个数字,于是。。。
var index = 2; //数字3在数组中的下标
var amount = 1; //从数组的位置index开始删除数字的个数 var num = arr.splice( index, amount); //从arr数组的下标2开始删除一个数字,并将被删除的数字赋值到num
哇,用 splice 来删除数组元素好简单啊,于是我开开心心地用到 for 循环里面。。。
var arr = new Array(1, 2, 3, 4, 5); //初始化数字集合
var delete_number = 3; //要被删除的数字 //遍历数组
for(var i=0; i<arr.length; i++){
if(arr[i] === delete_number){ //如果找到要被删除的数字所在的数组下标
var num = arr.splice( i, 1 ); //从i位置开始删除1个数字
console.log("成功删除 "+num); //输出被删除的数字
}
else{
console.log(arr[i]+" 未被删除"); //如果i下标的数组元素不是需要被删除的数字,就输出数字
}
}
哈哈,讨厌的数字3肯定被删掉了。不过还是要看一下调试信息。。。
看见没有,数字3果然被删掉了!!!哈哈哈哈,不过仔细一看,咦,4呢???????可爱的数字4没有被循环遍历到。。。
前面说过,splice 是直接操作并修改数组的,所以当找到数字3时在循环中的 i 下标是2,而当删除数字3后,数组下标 i 位置中保存的数字变为了数字4,然后到了下一个循环 i 下标为3时,数组下标 i 位置中保存的数字是5,所以跳过了数字4,于是调试信息中没有可爱的数字4.。。。原理就是这样子,是不是很绕。
题外话:因为我的疏忽,在一个for循环中加入了 splice 后,导致了我的H5游戏项目中的众多 NPC 中的某一个 NPC 并没有按预期地移动到相应的位置。最重要的是我还提交到了版本库,与 splice 同时提交了几百行代码,所以不能回退版本只能断点调试到深夜才找到这么小小错误。所以我写了这篇文章来记录一下在 for 循环中使用 splice 的坑。
说了这么多,怎么解决漏掉了数字4这个问题呢???很简单,在使用 splice 的下一句,改一下循环变量值即可。。。
if(arr[i] === delete_number){ //如果找到要被删除的数字所在的数组下标
var num = arr.splice( i, 1 ); //从i位置开始删除1个数字
console.log("成功删除 "+num); //输出被删除的数字
i = i-1; //解决方案
}
看完以上内容,是不是觉得特别简单而且小菜一碟,等一下,我要确保你不会向我一样犯 splice 引起的低级错误,所以请看以下代码,比以上的稍微复杂一点点,如果你仅根据代码推出的答案跟结果一样,就能确保下次使用 splice 时会有意识避开问题了。。。
var arr = new Array(1, 2, 3, 4, 5); //初始化数字集合
var delete_number = 3; //要被删除的数字
var amount = 2; ////从数组的某位置开始删除数字的个数 var loop = arr.length; //循环次数 //遍历数组
for(var i=0; i < loop; i++){
if(arr[i] === delete_number){ //如果找到要被删除的数字所在的数组下标
var num = arr.splice( i, amount ); //从i位置开始删除1个数字 i = i - 1; //改变循环变量
loop = loop - amount; //改变循环次数 }
else{
console.log( arr[i] + ", ");
}
} //结果:1,2,5
JS的splice()方法在for循环中使用可能会遇到的坑的更多相关文章
- (转)JS的splice()方法在for循环中的使用问题
在写JS代码时,我们常常使用 splice 函数来删除数组中的元素,因为 splice 函数会直接对数组进行修改,从而不需再自己写一个算法来移动数组中的其他元素填补到被删除的位置.splice 功能十 ...
- JS对象 substring() 方法用于提取字符串中介于两个指定下标之间的字符。
提取字符串substring() substring() 方法用于提取字符串中介于两个指定下标之间的字符. 语法: stringObject.substring(starPos,stopPos) 参 ...
- AngularJS例子 ng-repeat遍历输出 通过js的splice方法删除当前行
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- js的splice方法
splice是js原生处理数组的方法,可以在不改变引用的情况下对数组处理 arrayObject.splice(index,howmany,item1,.....,itemX)参数 描述index 必 ...
- splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目
删除位于 index 2 的元素,并添加一个新元素来替代被删除的元素: <script type="text/javascript"> var arr = new Ar ...
- Vue 实际项目中你可能会遇见的坑
纸上得来终觉浅,绝知此事要躬行! Vue的文档和教程看的太多,小的demo做的多,也不如自己实际的进行一个完整项目的开发.只有做了才知道原来问题这么多,这里列举了一些你做demo教程可能不会遇见的坑. ...
- JS中的splice方法
JS中的splice方法 定义和用法 splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目. 注释:该方法会改变原始数组(集合). 语法 arrayObject.splice(ind ...
- 关于js中splice方法返回的结果
一.前言 刚刚在使用splice()方法,发现这个方法返回的是删除后的数组元素,如果要获取删除指定元素后的数组,直接调用原来的数组即可!因为splice()会改变原来数组!之前对splice()方法一 ...
- 数组中的元素 增加push用法 unshift() 方法 和减少pop() 方法 shift() 和其他位置增删 splice() 方法 join() 方法 reverse() 方法 sort() 方法
push用法 push 英 [pʊʃ] 美 [pʊʃ] vt. 推,推动; vt. 按; 推动,增加; 对…施加压力,逼迫; 说服; n. 推,决心; 大规模攻势; 矢志的追求 定义和用法 push( ...
随机推荐
- 【转】Python+opencv利用sobel进行边缘检测(细节讲解)
#! usr/bin/env python # coding:utf-8 # 2018年7月2日06:48:35 # 2018年7月2日23:11:59 import cv2 import numpy ...
- mysql数据库内容相关操作
第一:介绍 mysql数据内容的操作主要是: INSERT实现数据的插入 UPDATE实现数据的更新 DLETE实现数据的删除 SELECT实现数据的查询. 第二:增(insert) 1.插入完整的数 ...
- cadence布线完成后的补充操作
完成布线之后,需要生成光绘文件和钻孔文件,在生成钻孔文件之前,还有几点补充!
- java实现多线程使用多个代理ip的方式爬取网页页面内容
项目的目录结构 核心源码: package cn.edu.zyt.spider; import java.io.BufferedInputStream; import java.io.FileInpu ...
- ps入门学习
快捷键 打开 ctrl+O 切换显示窗口 ctrl+tab 隐藏工具栏和面板 tab 只隐藏面板不隐藏工具栏 shift+tab 切换屏幕模式 F 文件的新建与格式 1.新建文档Ctrl+N,存 ...
- ubuntu 16.04卸载不必要默认安装软件
两个办法,一个在ubuntu软件里一个一个删,明显的windows下做法. 还有一个通过终端来删除.ctrl+alt+t打开终端. 1.卸载libreoffices(要删一起删了,然后去装office ...
- Roslyn还出现这么低级的错误,不应该呀!
前几天对Dora.Interception作了简单的重构,想提供C#脚本来定义Interception Policy,毫无疑问微软提供的编译平台Roslyn使C#脚本化提供了支持.但是没有想到随便尝试 ...
- 贪心算法----区间覆盖问题(POJ2376)
题目: 题目的大概意思是约翰这个农民有N条牛,这些牛可以在一天中的某个时间段可以进行工作,他想把这个时间段分成若干个片段让这些牛去进行打扫任务,你的任务是安排尽量少的牛然后可以完成分成这些片段的打扫任 ...
- FFmpeg 结构体学习(五): AVCodec 分析
在上文FFmpeg 结构体学习(四): AVFrame 分析我们学习了AVFrame结构体的相关内容.本文,我们将讲述一下AVCodec. AVCodec是存储编解码器信息的结构体.下面我们来分析一下 ...
- Python爬虫7-Cookie & Session
GitHub代码练习地址:1.手动利用cookie访问网页:https://github.com/Neo-ML/PythonPractice/blob/master/SpiderPrac10_cook ...