引用类型之 Array(二)

本章将介绍 Array 的构造函数的属性,也就是 prototype 上的方法,这一节内容挺多的。所以理解和消化需要一定的时间。那么,我们开始吧~

(1)Array.prototype.concat ( …arguments )

概述:concat() 方法 将传入的数组或非数组值与原数组合并,组成一个新的数组并返回。

示例:

let a = [1];
let b = a.concat([2],3);
console.log(b);  // [1,2,3]

需要注意的是:该方法返回一个新的数组,不会改变原数组。

内部解释时也很简单,就是将传入的数组展开,作为 List 传入先前数组的后面。

(2)Array.prototype.copyWithin (* target, start [ , end ]* )

概述:copyWithin() 方法会浅拷贝数组的部分元素到同一数组的不同位置,且不改变数组的大小,返回该数组。

这个方法看起来就觉得很奇葩。。比如:

let a = [1,2,3];
a.copyWithin(0,1);

你觉得他会返回什么值?是 [2,3,3]。我不否认他可能在某些方面会出众,但我是觉得这个方法很难去理解。我个人认为这个方法还是挺反人类的,需要使用很长的时间去思考到底需要截取和替换哪些值。但如果理解了,它也不失为一个好方法。

(3)Array.prototype.entries ( )

概述:entries() 方法返回一个 Array Iterator 对象,该对象包含数组中每一个索引的键值对。

示例:

let a = [1,2,3];
let b = a.entries();
console.log(b.next().value);  // [0, 1]

如果你不知道什么可迭代。那我觉得可以去好好的回顾下。这个方法也很简单,使用场景暂时不详。

(4)Array.prototype.every ( callbackfn [ , thisArg ] )

概述:every() 方法测试数组的所有元素是否都通过了指定函数的测试。

很简单啦:

let a = [1,2,3];
console.log(a.every(x => x > 2));  // false

注意:该方法返回的是 truefalse

(5)Array.prototype.fill ( value [ , start [ , end ] ] )

概述:fill() 方法,可以将一个数组中指定区间的所有元素的值, 都替换成或者说填充成为某个固定的值。

示例:

[1, 2, 3].fill(4);  // [4, 4, 4]
[1, 2, 3].fill(4, 1);  // [1, 4, 4]
[1, 2, 3].fill(4, 1, 2);  // [1, 4, 3]

我不知道你看到它是什么想法。但是对我个人而言,这个方法的理解性与可实现性远高于前面讲的 copyWithin 方法。

(6)Array.prototype.filter ( callbackfn [ , thisArg ] )

概述:filter() 方法使用指定的函数测试所有元素,并创建一个包含所有通过测试的元素的新数组。

示例:

let a = [1,2,3];
console.log(a.filter(x => x > 2)); // [3]

这个方法呢,用的还是以较多的,主要用于数组值的筛选,仅留下我们需要的值。

(7)Array.prototype.find ( predicate [ , thisArg ] )

概述:如果数组中某个元素满足测试条件**,find() **方法就会返回那个元素的第一个值,如果没有满足条件的元素,则返回 undefined。

示例:

let a = [1,2,3];
console.log(a.find(x => x > 1));  // 2
console.log(a.find(x => x > 3));  // undefined

注意,该方法返回的是第一个值,也就说即使上述表达式中有 2 个值满足,但其只返回符合条件的第一个值。因此,我个人认为,该方法并不是让你寻找值的,而是判断是否存在满足条件的值。也可以结合其它的方法进行组合,筛选出符合条件的值。

(8)Array.prototype.findIndex (* predicate [ , thisArg ]* )

概述:findIndex() 方法用来查找数组中某指定元素的索引, 如果找不到指定的元素, 则返回 -1。

示例:

let a = [1,2,3];
console.log(a.findIndex(x => x > 1)); // 1
console.log(a.findIndex(x => x > 3)); // -1

这个方法是 ES6 新增的方法。

该方法是不是很像 String 中的 indexOf 方法呢?

(9)Array.prototype.forEach ( callbackfn [ , thisArg ] )

概述:forEach() 方法对数组的每个元素执行一次提供的函数(回调函数)。

相信大家对这些方法都已经很熟练了。示例:

let a = [1,2,3];
a.forEach( x => {
    console.log(x + 1);
});
// 2
// 3
// 4

(10)Array.prototype.includes ( *searchElement [ , fromIndex ] *)

概述:includes() 方法用来判断当前数组是否包含某指定的值,如果是,则返回 true,否则返回 false。

示例:

let a = [1,2,3];
a.includes(2);  // true
a.includes(4);  // false

(11)Array.prototype.indexOf / lastIndexOf ( searchElement [ , fromIndex ] )

概述:indexOf() 方法返回给定元素能找在数组中找到的第一个索引值,否则返回 -1。

示例:

var array = [2, 5, 9];
array.indexOf(2); // 0
array.indexOf(7); // -1

(12)Array.prototype.join ( separator )

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

示例:

let a = [1,2,3];
console.log(a.join(' ')); // 1 2 3

(13)Array.prototype.keys ( )

概述:keys() 方法返回一个数组索引的迭代器。

这是 ES6 中新增加的方法。

let a = [1,2,3];
let b = a.keys();
console.log(b.next());  // {value: 0, done: false}

(14)Array.prototype.map ( callbackfn [ , thisArg ] )

概述:map() 方法返回一个由原数组中的每个元素调用一个指定方法后的返回值组成的新数组。

这个方法是我很喜爱的方法,因为它真的是很方便。

示例:

let a = [1,2,3];
console.log(a.map(x => x + 1));  // [2, 3, 4]

(15)Array.prototype.pop ( )

概述:pop() 方法删除一个数组中的最后的一个元素,并且返回这个元素。

示例:

let a = [1,2,3];
console.log(a.pop());  // 3
console.log(a);  // [2, 3]

需要注意的是,使用这个方法,将会改变原数组!所以谨慎使用它。如不想破坏原数组,可以配合其他方法,将其复制后再进行删除。

例如:

let a = [1,2,3];
let b = [...a];
console.log(b.pop());  // 3
console.log(b);  // [2, 3]
console.log(a);  // [1, 2, 3]

这样,就不会改变原数组了。

注意:改变数组的方法,使用 const 是没有用的,并不能够限制它能改变数组。这是因为,所谓的 const 仅仅是不可再更改值,并不能约束 prototype 上的方法。

(16)Array.prototype.push ( …items )

概述:push() 方法添加一个或多个元素到数组的末尾,并返回数组新的长度(length 属性值)。

该方法也会改变原有的数组。

示例:

const a = [1,2,3];
a.push(4);
console.log(a);  // [1, 2, 3, 4]

(17)Array.prototype.reduce / reduceRight( callbackfn [ , initialValue ] )

reduce() 方法接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始合并,最终为一个值。

示例:

const a = [1,2,3];
console.log(a.reduce((x,y) => x * y)); // 6

该方法至少需要两个参数哦,不然是没有用滴。

(18)Array.prototype.reverse ( )

概述:reverse() 方法颠倒数组中元素的位置。第一个元素会成为最后一个,最后一个会成为第一个。

示例:

const a = [1,2,3];
console.log(a.reverse());  // [3, 2, 1]

(19)Array.prototype.shift ( )

概述:shift() 方法删除数组的 第一个 元素,并返回这个元素。该方法会改变数组的长度。

示例:

const a = [1,2,3];
a.shift();
console.log(a); // [2, 3]

(20)Array.prototype.slice ( start, end )

概述:slice() 方法会浅复制(shallow copy)数组的一部分到一个新的数组,并返回这个新数组。

示例:

const a = [1,2,3];
const b = a.slice(0);
console.log(b);  // [1, 2, 3]

这是自然而然的结果啦。相似的,这里的浅复制与 Object.assign() 的浅复制一样。

依旧使用上述的方法:

delete b[0];
console.log(b);  // [undefined, 2, 3]
console.log(a);  // [1, 2, 3]

也就是说,这里是浅复制,虽然是使用原内存地址的复制,但确实与原数组分离开来。而我们来看看 Object.assign() 方法是什么样的吧。

const obj = {
    a: 1,
    b: 2
};
const obj1 = Object.assign({},obj) ;
delete obj1['a']
console.log(obj);  // {a: 1, b: 2}
console.log(obj1);  // {b: 2}

好的,验证完成,没有任何问题。

另外,都 ES6 了,我能可以使用更先进的方法吗?当然有啦:

const a = [1,2];
const b = [...a];
console.log(b);  // [1,2]

更加方便快捷不是吗?但是你要问了。。我要是只需要原数组其中一部分怎么办?有办法!

let a = [1,2,3,4,5];
const [x,,...y] = a;
console.log(y);  // [3, 4, 5]

与我们前面讲到的解构相结合,就可以选取我们想要的部分啦。当然了,这个方法还是有一定的问题的,由于这里的 ... 操作符代表剩余参数,所以它只能放在最后。我们要截取中间,那就不太合适啦。使用该方法会更好。

(21)Array.prototype.some ( callbackfn [ , thisArg ] )

概述:some() 方法测试数组中的某些元素是否通过了指定函数的测试。

顾名思义,“some”表示一些、某些的意思。所以,也就是说,只要有通过回调函数的,都可以返回 true。

let a = [1,2,3,4,5];
console.log(a.some(x => x > 4));  // true
console.log(a.some(x => x > 6));  // false 

换句话说,只要有一个参数符合条件,即返回 true。

(22)Array.prototype.sort ( comparefn )

概述:sort() 方法对数组的元素做排序,并返回这个数组。 sort 排序可能是不稳定的。默认按照字符串的Unicode 码位点(code point)排序。

首先声明我的观点吧,我不是很建议使用这个方法,因为它真的十分鸡肋。特别是对字符串而言,基本就是按照首字母在字母表中的排序来的;那么数字呢?来看看吧:

let a = [1,12,11,16,122];
console.log(a.sort());

如果你认为返回结果是 [1,11,12,16,122],那么你就错啦。

现实生生打了我们的脸。它的结果是:[1, 11, 12, 122, 16]

这也就是我所说的“不靠谱”,如果我们使用这个方法排序,那么其中又有多少坑需要填呢?

(23)Array.prototype.splice ( start, deleteCount, …items )

splice() 方法用新元素替换旧元素,以此修改数组的内容。

该方法会破坏原数组。

我们可以将此方法想象成一把“剪刀”,可以从原数组中剪出你需要的部分,同时,你还可以给它填充进去别的东西。

示例:

// 截取
let a = [1,2,3,4,5];
console.log(a.splice(1,2));  // [2, 3]
console.log(a);  // [1, 4, 5]

以上的示例表示从数组的第 2 个索引处开始用剪刀剪,直到第 3 个索引处(包括它),返回截取的这一段内容。

// 截取与填充(替换)
let a = [1,2,3,4,5];
console.log(a.splice(1,2,8,9));  // [2, 3]
console.log(a);  // [1, 8, 9, 4, 5]

这时,原数组就被填充进所写入的参数了。这里需要注意,如果你在后面用了数组的话,里面就会嵌套数组哦,这可能不是你想要的结果。

let a = [1,2,3,4,5];
console.log(a.splice(1,2,[8,9]));  // [2, 3]
console.log(a);  // [1, [8, 9], 4, 5]

好了,这一个知识到此结束啦。

(24)Array.prototype.unshift ( …items )

概述:unshift() 方法在数组的开头添加一个或者多个元素,并返回数组新的 length 值。

这个方法和 shift 方法是一对双胞胎,就像 pop 与 push 的关系一样。需要记住哦。

let a = [1,2,3,4,5];
console.log(a.unshift(10));  // 6
console.log(a);  // [10, 1, 2, 3, 4, 5]

很简单对吧。

(25)Array.prototype.values ( )

values() 方法返回一个新的 Array Iterator 对象,该对象包含数组每个索引的值。

这个方法,貌似浏览器还未支持。目前使用时,显示如下错误:
Uncaught TypeError: arr.values is not a function(…)

未来支持了,再回来做更改吧。暂时跳过该方法。

总结

本节讲了几乎全部的 Array 的原型方法,里面的很多东西都是大家所熟知的,所以可以选择性地进行浏览。也可以再好好复习一遍,也不枉我花了这么多时间打字。谢谢。

    原文作者:Hushaby丶
    原文地址: https://www.jianshu.com/p/8dd1af6d868e
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞