-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Javascripts数组原生方法集合 #5
Comments
总结的很好~ |
这么全,怎么总结的,厉害了.... |
@yangzaiwangzi ES3和5找了W3C里的内容,ES6和7找了mdn,后面发现mdn里面什么都有。。。 |
includes 可以用来判断数组是否包含NaN indexOf 不能 var arr = [1,2,NaN]; arr.includes(NaN) // true; arr.indexOf(NaN) // -1 |
@each-Li 对的,这一点忘记补充了,谢谢提醒 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
github格式看不惯的的可以来这里看
1 ES3中的数组方法
ES3中的方法毫无疑问大家已经烂熟在心了,不过中间有些细节可以回顾加深一下记忆,比如是否修改原数组返回新数组,执行方法之后的返回值是什么,某些参数的意义是否搞混等等。熟悉的的可以直接快速浏览或者跳过。
1.1 join()方法
Array.join()方法是将一个数组里面的所有元素转换成字符串,然后再将他们连接起来返回一个新数组。可以传入一个可选的字符串来分隔结果字符串中的所有元素。如果没有指定分隔字符串,就默认使用逗号分隔。
1.2 reverse()方法
Array.reverse()方法将颠倒数组中元素的顺序并返回一个颠倒后的数组。它在原数组上执行这一操作,所以说并不是创建了一个新数组,而是在已存在的数组中对元素进行重排。
1.3 sort()方法
Array.sort()是在原数组上进行排序,返回排序后的数组。如果调用方法时不传入参数,那么它将按照字母顺序对数组元素进行排序,说得更精确点,是按照字符编码的顺序进行排序。要实现这一点,首先应把数组的元素都转换成字符串(如有必要),以便进行比较。
如果数组中有未定义的元素,这些元素将放在数组的末尾
仔细看可以发现,上面顺序并没有按照数字大小进行排序。如果想按照其他标准进行排序,就需要提供比较函数。该函数比较前后两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,其返回值如下:
1.4 concat()方法
Array.concat() 方法用于连接两个或多个参数(数组,字符串等),该方法不会改变现有的数组,而会返回连接多个参数的一个新数组。如果传入的参数是数组,那么它将被展开,将元素添加到返回的数组中。但要注意,concat并不能递归的展开一个元素为数组的参数。
1.5 slice()方法
Array.slice() 方法可从已有的数组中返回指定的一个片段(slice),或者说是子数组。它是从原数组中截取了一个片段,并返回到了一个新数组。
Array.slice(a,b) 它有两个参数a,b
请注意,该方法并不会修改数组,而是返回一个新的子数组。如果想删除数组中的一段元素,应该使用下面这个方法 Array.splice()。
1.6 splice()方法
Array.splice() 方法从数组中添加/删除元素,然后返回被删除的元素。它在原数组上修改数组,并不像slice和concat那样创建新数组。注意,虽然splice和slice名字非常相似,但是执行的却是完全不同的操作。
大家要记住slice()和splice()两个方法第二个参数代表的意义是不一样的。虽然这很基础,可是有时候还是会弄混。
1.7 push()和pop()方法
Array.push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度。
Array.pop()方法用于删除并返回数组的最后一个元素。如果数组已经为空,则 pop() 不改变数组,并返回 undefined 值。
上面两个方法都是直接对原数组进行操作。通过上面两个方法可以实现一个先进后出的栈。
1.8 unshift和shift()方法
unshift,shift()的方法行为和push(),pop()非常相似,只不过他们是对数组的头部元素进行插入和删除。
Array.unshift() 方法可向数组的头部添加一个或多个元素,并返回新的长度。
Array.shift()方法用于删除并返回数组的第一个元素。如果数组已经为空,则 pop() 不改变数组,并返回 undefined 值。
1.9 toString()和toLocaleString()方法
和所有javascript的对象一样,数组也有toString()方法,这个方法可以将数组的每一个元素转化成字符串(如果必要的话,就调用元素的toString()方法),然后输出字符串的列表,字符串之间用逗号隔开。(用我的话来理解,其实就是遍历数组元素调用每个元素自身的toString()方法,然后用逗号连接)
toString()的返回值和没有参数的join()方法返回的字符串相同
注意,输出的结果中,返回的数组值周围没有括号。
toLocaleString方法是toString()方法的本地化版本。它是使用地区特定的分隔符把生成的字符串连接起来,形成一个字符串。
虽然是两个方法,但是一般元素两个方法的输出结果却基本是一样的,去网上找了相关文章,发现只有两种情况比较有区分,一个是时间,一个是4位数字以上的数字,举例如下
好吧,这个api和数组关系不大。。。主要还是和数组中元素自身有关。啊哈哈,尴尬。
1.10 valueOf()
Array.valueOf()方法在日常中用的比较少,该方法继承与Object。javascript中许多内置对象都针对自身重写了该方法,数组Array.valueOf()直接返回自身。
2 ES5中的数组方法
2.Array在ES5新增的方法中接受两个参数,第一个参数都是function类型,必选,默认有传参,这些参数分别是:
第二个参数是当执行回调函数时指向的this(参考对象),不提供默认为window,严格模式下为undefined。
以forEach举例
语法
例子:
3.ES5中的所有关于遍历的方法按升序为数组中含有效值的每一项执行一次callback函数,那些已删除(使用delete方法等情况)或者未初始化的项将被跳过(但不包括那些值为 undefined 的项)(例如在稀疏数组上)。
例子:数组哪些项被跳过了
好了,上面3点基本上是ES5中所有方法的共性,下面就不重复述说了。开始正文解析每个方法的不同了
2.1 forEach()
Array.forEach() 为每个数组元素执行callback函数;不像map() 或者reduce() ,它总是返回 undefined值,并且不可链式调用。典型用例是在一个链的最后执行副作用。
例子:如果数组在迭代时被修改了
下面的例子输出"one", "two", "three"。当到达包含值"two"的项时,整个数组添加了一个项在第一位,这导致所有的元素下移一个位置。此时在下次执行回调中,因为元素 "two"符合条件,结果一直增加元素,直到遍历次数完毕。forEach()不会在迭代之前创建数组的副本。
看完例子可以发现,使用 forEach 方法处理数组时,数组元素的范围是在callback方法第一次调用之前就已经确定了。在 forEach 方法执行的过程中:原数组中新增加的元素将不会被 callback 访问到;若已经存在的元素被改变或删除了,则它们的传递到 callback 的值是 forEach 方法遍历到它们的那一个索引时的值。
2.2 map()
Array.map 方法会给原数组中的每个元素都按顺序调用一次callback函数。callback每次执行后的返回值(没有指定返回值则返回undefined)组合起来形成一个新数组。
例子:返回每个元素的平方根的数组
2.3 filter()
Array.filter()为数组中的每个元素调用一次 callback 函数,并利用所有使得 callback 返回 true 或 等价于 true 的值 的元素创建一个新数组。那些没有通过 callback 测试的元素会被跳过,不会被包含在新数组中
例子:数组去重
2.4 some()
Array.some 为数组中的每一个元素执行一次 callback 函数,直到找到一个使得 callback 返回一个“真值”(即可转换为布尔值 true 的值)。如果找到了这样一个值,some 将会立即返回 true。否则,some 返回 false。callback 只会在那些”有值“的索引上被调用,不会在那些被删除或从来未被赋值的索引上调用。
例子:查看数组内是否含有大于0的元素
2.5 every()
Array.every() 方法为数组中的每个元素执行一次 callback 函数,直到它找到一个使 callback 返回 false(表示可转换为布尔值 false 的值)的元素。如果发现了一个这样的元素,every 方法将会立即返回 false。否则,callback 为每一个元素返回 true,every 就会返回 true。callback 只会为那些已经被赋值的索引调用。不会为那些被删除或从来没被赋值的索引调用。
例子:检测所有数组元素的大小,是否都大于0
2.6 indexOf()
Array.indexOf()使用严格相等(strict equality,即===)进行判断searchElement与数组中包含的元素之间的关系。
Array.indexOf()提供了两个参数,第一个searchElement代表要查询的元素,第二个代表fromIndex表示从哪个下标开始查找,默认为0。
语法
Array.indexOf()会返回首个被找到的元素在数组中的索引位置; 若没有找到则返回 -1
例子:
2.7 lastIndexOf()
Array.lastIndexOf()就不细说了,其实从名字大家也可以看出来,indexOf是正向顺序查找,lastIndexOf是反向从尾部开始查找,但是返回的索引下标仍然是正向的顺序索引
。
语法
例子:各种情况下的的indexOf
2.8 reduce()
Array.reduce() 为数组中的每一个元素依次执行回调函数,最后返回一个函数累计处理的结果。
语法
reduce的回调函数中的参数与前面的不同,多了第一个参数,是上一次的返回值
例子:数组求和
对了,当回调函数第一次执行时,accumulator 和 currentValue 的取值有两种情况:
例子:reduce数组去重
2.9 reduceRight()方法
Array.reduceRight() 为数组中的每一个元素依次执行回调函数,方向相反,从右到左,最后返回一个函数累计处理的结果。
因为这个方法和reduce方法基本是一模一样的,除了方法相反,所以就不详细的再写一遍了
2.10 isArray()方法
之所以将这个方法放在最后,是因为这个方法和前面的不太一致,是用于确定传递的值是否是一个 Array,使用方法也很简单
例子
不过感觉除非是临时判断,不然一般也不会用这个方法去判断,一般还是下面这种万金油型的吧。
3 ES6中的数组方法
3.1 ...方法——concat方法的增强
英文名字叫做Spread syntax,中文名字叫做扩展运算符。这个方法我不知道怎么描述,感觉更像是原有concat()方法的增强,可以配合着解构一起使用,大家还是直接看例子感受以下吧
例子:简单拷贝数组
可以看到这个方法对于引用类型仍然是浅复制,所以对于数组的深拷贝还是需要用额外的方法,可以看我另外一篇文章
3.2 of()方法
Array.of()方法可以将传入参数以顺序的方式返回成一个新数组的元素。
其实,刚看到这个api和他的用途,还是比较懵逼的,因为看上去这个方法就是直接将传入的参数变成一个数组之外,就没有任何区别了,那么我为什么不直接用以前的写法去实现类似的效果呢,比如 let = [1,2,3];而且看上去也更加直接。然后我去翻了下最新的ECMAScript草案,其中有这么一句话
自己理解了一下,其实大概意思就是说为了弥补Array构造函数传入单个函数的不足,所以出了一个of这个更加通用的方法,举个例子
大家可以注意到传入一个参数和传入两个参数的结果,完全是不一样的,这就很尴尬了。而为了避免这种尴尬,es6则出了一种通用的of方法,不管你传入了几个参数,都是一种相同类型的输出结果。
不过我好奇的是,如果只传入几个参数,为什么不直接let a = [1,2,3];效率和直观性也更加的高。如果要创建一个长度的数组,我肯定还是选let a = new Array(10000),这种形式,实在没有感觉到Array.of的实用场景,希望大家可以给我点指导。
3.2 from()方法
Array.from()方法从一个类似数组(拥有一个 length 属性和若干索引属性的任意对象)或可迭代的对象(String, Array, Map, Set和 Generator)中创建一个新的数组实例。
我们先查看Array.from()的语法
语法
从语法中,我们可以看出Array.from()最基本的功能是将一个类数组的对象转化成数组,然后通过第二个和第三个参数可以对转化成功后的数组再次执行一次遍历数据map方法,也就是Array.from(obj).map(mapFn, thisArg)。
例子 :将一串数字字符串转化为数组
3.4 copyWithin()方法
Array.copyWithin方法,在当前数组内部,将指定位置的成员浅复制到其他位置(会覆盖原有成员),然后返回当前数组。也就是说,使用这个方法,会修改当前数组。
语法
例子
第一个是常规的例子,大家可以对比看第二个可以发现,这个方法是先浅复制了数组一部分暂时存储起来,然后再从目标索引处开始一个个覆盖后面的元素,直到这段复制的数组片段全部粘贴完。
再看第三个例子,可以发现当复制的数据片段从目标索引开始粘贴时,如果超过了长度,它将停止粘贴,这说明它不会改变数据的 length,但是会改变数据本身的内容。
Array.copyWithin可以理解成复制以及粘贴序列这两者是为一体的操作;即使复制和粘贴区域重叠,粘贴的序列也会有拷贝来的值。
3.5 find() 和 findIndex()方法
Array.find()方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。
Array.findIndex() 方法返回数组中满足提供的测试函数的第一个元素的值的索引。否则返回 -1。
这两个方法其实使用非常相似,使用场景有点像ES5中Array.some,都是在找到第一个满足条件的时候,跳出循环,区别的是,三种返回的值完全不一样,我想这也许是为什么要在ES6中增加这两个API的原因吧,可以理解成是数组的方法的补足。
例子:三个方法各自的返回值
其实还可以发现,Array.find() 方法只是返回第一个符合条件的元素,它的增强版是es5中Array.filter()方法,返回所有符合条件的元素到一个新数组中。可以说是当用find方法时考虑跟多的是跳出吧。
我感觉这4个方法配合相应的回调函数基本上可以完全覆盖大多数需要数组判断的场景了,大家觉得呢?
3.5 fill方法
Array.fill()方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素,返回原数组
这个方法的使用也非常简单,大家基本上看个语法和demo就能懂了。需要注意的是,这个方法是返回数组本身,还有一点就是,类数组不能调用这个方法,刚刚自己去改了MDN上面的文档。
语法
例子
3.6 entries(),keys(),values()方法
Array.entries()将数组转化成一个中包含每个索引的键/值对的Array Iterator对象
Array.keys()将数组转化成一个中包含每个索引的键的Array Iterator对象
Array.values()将数组转化成一个中包含每个索引的值的Array Iterator对象。
之所以将这三个方法放在一起是有原因的额,大家可以看这三个方法其实都是一个数组转化为一种新的数据类型——返回新的Array Iterator对象,唯一区别的是转化之后的元素不一样。跟他们的名字一样,entries()方法转化为全部的键值对,key()方法转化为键,value()保留值。
例子:观察各个迭代器遍历输出的东西
Array.entries()
Array.keys()
Array.values()
4 ES7中的数组方法
4.1 includes()方法
Array.includes方法返回一个布尔值,表示某个数组是否包含给定的值,如果包含,则返回true,否则返回false,与字符串的includes方法类似。
这个方法大家可以看作是ES5中Array.indexOf的语义增强版,“includes”这个是否包含的意思,直接返回Boolean值,比起原来的indexOf是否大于-1,显得更加直观,我就是判断有没有包含哪个值
对了,Array.includes()相比起indexOf这个方法还有一个增强之处是可以判断NaN。
语法,使用方法和indexof一模一样
例子
方法还真是tmd多啊,感觉基本上应该是更新完了,前后两星期花了我4天时间吧,还是挺累的。不过收货还是很多,比如知道了ES5的方法基本上都有第二个this指向的参数,重新认识了reduce方法,感觉自己之前很多场景用reduce更好,重新熟悉了一些ES6的方法可以试用有些场景
如果能看到最后的,感觉你也是够累的,哈哈哈。
The text was updated successfully, but these errors were encountered: