不会改变自身的数组方法(9个)【中篇】

基于ES7,不会改变自身的方法一共有9个,分别为concat、join、slice、toString、toLocateString、indexOf、lastIndexOf、未标准的toSource以及ES7新增的方法includes。

一、concat

concat() 方法将传入的数组或者元素与原数组合并,组成一个新的数组并返回。

1、语法:arr.concat(value1, value2, …, valueN)

var array = [1, 2, 3]; 
var array2 = array.concat(4,[5,6],[7,8,9]); 
console.log(array2); // [1, 2, 3, 4, 5, 6, 7, 8, 9] 
console.log(array); // [1, 2, 3], 可见原数组并未被修改
复制代码

2、若concat方法中不传入参数,那么将基于原数组浅复制生成一个一模一样的新数组(指向新的地址空间)。

var array = [{a: 1}]; 
var array3 = array.concat(); 
console.log(array3); // [{a: 1}] 
console.log(array3 === array); // false 
console.log(array[0] === array3[0]); // true,新旧数组第一个元素依旧共用一个同一个对象的引用
复制代码

3、同上,concat 一样受益于鸭式辨型,但其效果可能达不到我们的期望,如下:

image.png

可见,类数组对象合并后返回的依旧是数组,只是它并不是我们期待的数组的样子。

二、join

join() 方法将数组中的所有元素连接成一个字符串。

1、语法:arr.join([separator = ‘,’])  separator可选,缺省默认为逗号。

var array = ['We', 'are', 'Chinese']; 
console.log(array.join()); // "We,are,Chinese" 
console.log(array.join('+')); // "We+are+Chinese" 
console.log(array.join('')); // "WeareChinese"
复制代码

2、同上,join 一样受益于鸭式辨型,如下:

var o = {0:"We", 1:"are", 2:"Chinese", length:3}; 
console.log(Array.prototype.join.call(o,'+')); // "We+are+Chinese" 
console.log(Array.prototype.join.call('abc')); // "a,b,c"
复制代码

三、slice

slice() 方法将数组中一部分元素浅复制存入新的数组对象,并且返回这个数组对象。

1、语法:arr.slice([start[, end]])

(1)参数start是开始复制的元素的索引, end是结束复制的元素索引

特别注意:复制的元素包括start,不包括end

(2)不会改变数组本身的值,slice方法会返回浅复制的元素组成的新数组。

例子如下:

image.png

(3)如果 start 的值为负数,假如数组长度为 length,则表示从 length+start 的位置开始复制,此时参数 end 如果有值,只能是比 start 大的负数,否则将返回空数组。

image.png

(4)slice方法参数为空时,同concat方法一样,都是浅复制生成一个新数组。

image.png

浅复制 是指当对象的被复制时,只是复制了对象的引用,指向的依然是同一个对象。下面来说明slice为什么是浅复制。

var array = [{color:"yellow"}, 2, 3]; 
var array2 = array.slice(0,1); 
console.log(array2); // [{color:"yellow"}] 
array[0]["color"] = "blue"; 
console.log(array2); // [{color:"bule"}]
复制代码

由于slice是浅复制,复制到的对象只是一个引用,改变原数组array的值,array2也随之改变。

(5)同时,稍微利用下 slice 方法第一个参数为负数时的特性,我们可以非常方便的拿到数组的最后一项元素,例子如下:

console.log([1,2,3].slice(-1));//[3]
复制代码

同上,slice 一样受益于鸭式辨型。例子如下:

image.png

对象中还需要有length属性,如果没有length属性,会显示undefined,并且会复制不成功。

image.png

四、toString

toString() 方法返回数组的字符串形式,该字符串由数组中的每个元素的 toString() 返回值经调用 join() 方法连接(由逗号隔开)组成。

(1)语法: arr.toString()

var array = ['Jan', 'Feb', 'Mar', 'Apr']; 
var str = array.toString(); 
console.log(str); // Jan,Feb,Mar,Apr
复制代码

(2)当数组直接和字符串作连接操作时,将会自动调用其toString() 方法。

var str = ['Jan', 'Feb', 'Mar', 'Apr'] + ',May'; 
console.log(str); // "Jan,Feb,Mar,Apr,May"
复制代码

(3)下面来看看鸭式辨型:

var o = {0:'Jan', 1:'Feb', 2:'Mar', length:3}; 
var o2 = Array.prototype.toString.call(o); 
console.log(o2); // [object Object] 
console.log(o.toString()==o2); // true
复制代码

可见,Array.prototype.toString()方法处理类数组对象时,跟类数组对象直接调用Object.prototype.toString()方法结果完全一致。

根据ES5语义,toString() 方法是通用的,可被用于任何对象。如果对象有一个join() 方法,将会被调用,其返回值将被返回,没有则调用Object.prototype.toString(),为此,我们给o对象添加一个join方法。例子如下:

image.png

五、toLocateString

toLocaleString() 类似toString()的变型,该字符串由数组中的每个元素的 toLocaleString() 返回值经调用 join() 方法连接(由逗号隔开)组成。

(1)语法:arr.toLocaleString()

数组中的元素将调用各自的 toLocaleString 方法:

例子如下:

image.png

(2)其鸭式辨型的写法也同toString 保持一致,例子如下:

image.png

六、indexOf

indexOf() 方法用于查找元素在数组中第一次出现时的索引,如果没有,则返回-1。

(1)语法:arr.indexOf(element, fromIndex=0)

element 为需要查找的元素。

fromIndex 为开始查找的位置,缺省默认为0。

如果超出数组长度,则返回-1。

如果为负值,假设数组长度为length,则从数组的第 length + fromIndex项开始往数组末尾查找,如果length + fromIndex<0 则整个数组都会被查找。

indexOf使用严格相等(即使用 === 去匹配数组中的元素,类型数值都要保持一致)。

var array = ['abc', 'def', 'ghi','123']; 

console.log(array.indexOf('def')); // 1 

console.log(array.indexOf('def',-1)); // -1  此时表示从最后一个元素往后查找,因此查找失败返回-1 ,类似于lastIndexOf方法

console.log(array.indexOf('def',-4)); // 1  由于4大于数组长度,此时将查找整个数组,因此返回1 

console.log(array.indexOf(123)); // -1, 由于是严格匹配,因此并不会匹配到字符串'123',类型不一致
复制代码

(2)得益于鸭式辨型,indexOf 可以处理类数组对象。例子如下:

var o = {0:'abc', 1:'def', 2:'ghi', length:3}; 
console.log(Array.prototype.indexOf.call(o,'ghi',-4));//2
复制代码

然而该方法并不支持IE9以下版本,如需更好的支持低版本IE浏览器(IE6~8), 请参考 Polyfill

image.png

七、lastIndexOf

lastIndexOf() 方法用于查找元素在数组中最后一次出现时的索引,如果没有,则返回-1。并且它是indexOf的逆向查找,即从数组最后一个往前查找。

(1)语法:arr.lastIndexOf(element, fromIndex=length-1)

element 为需要查找的元素。

fromIndex 为开始查找的位置,缺省默认为数组长度length-1。如果超出数组长度,由于是逆向查找,则查找整个数组。如果为负值,则从数组的第 length + fromIndex项开始往数组开头查找,如果length + fromIndex<0 则数组不会被查找。

(2)同 indexOf 一样,lastIndexOf 也是严格匹配数组元素。

举例请参考 indexOf ,

image.png

(3)兼容低版本IE浏览器(IE6~8),请参考 Polyfill

八、toSource(未标准)

toSource() 方法是非标准的,该方法返回数组的源代码,目前只有 Firefox 实现了它。

语法:arr.toSource()

var array = ['a', 'b', 'c']; 
console.log(array.toSource()); // ["a", "b", "c"] // 测试鸭式辨型 

var o = {0:'a', 1:'b', 2:'c', length:3}; 
console.log(Array.prototype.toSource.call(o)); // ["a","b","c"]
复制代码

九、includes(ES7新增的)

includes() 方法基于ECMAScript 2016(ES7)规范,它用来判断当前数组是否包含某个指定的值,如果是,则返回 true,否则返回 false。

(1)语法:arr.includes(element, fromIndex=0)

element 为需要查找的元素。

fromIndex 表示从该索引位置开始查找 element,缺省为0,它是正向查找,即从索引处往数组末尾查找。

var array = [-0, 1, 2]; console.log(array.includes(+0)); // true 
console.log(array.includes(1)); // true 
console.log(array.includes(2,-4)); // true
复制代码

以上,includes似乎忽略了 -0 与 +0 的区别,这不是问题,因为JavaScript一直以来都是不区分 -0 和 +0 的。

arr.indexOf(x)>-1不就等于arr.includes(x)?看起来是的,几乎所有的时候它们都等同,唯一的区别就是includes能够发现NaN,而indexOf不能。

image.png

该方法同样受益于鸭式辨型。 例子如下:

var o = {0:'a', 1:'b', 2:'c', length:3}; 
var bool = Array.prototype.includes.call(o, 'a'); 
console.log(bool); // true
复制代码

该方法只有在Chrome 47、opera 34、Safari 9版本及其更高版本中才被实现。如需支持其他浏览器,请参考 Polyfill

猜你喜欢

转载自juejin.im/post/7041444181696315399