JavaScript数组学习记录
Array.length
Array.length 是Array的实例属性。返回或设置一个数组中的元素个数。该值是一个无符号 32-bit 整数,并且总是大于数组最高项的下标。
- length 属性的值是一个 0 到
$2^{32}$
-1 的整数
let arr = ['1', '2', '3', '4','5'];
console.log(arr.length);
//output: 5
- 可以设置 length属性的值来截断任何数组。当通过改变length属性值来扩展数组时,实际元素的数目将会增加。例如:将一个拥有 2 个元素的数组的 length 属性值设为 3 时,那么这个数组将会包含3个元素,并且,第三个元素的值将会是 undefined 。
let numbers = [1, 2, 3, 4, 5];
let length = numbers.length;
for (let i = 0; i < length; i++) {
numbers[i] *= 2;
}
console.log(numbers);
//[2, 4, 6, 8, 10]
let numbers = [1, 2, 3, 4, 5];
if (numbers.length > 3) {
numbers.length = 3;
}
console.log(numbers); // [1, 2, 3]
console.log(numbers.length); // 3
- length属性不一定表示数组中定义值的个数。了解更多:长度与数值下标属性之间的关系。
Array.length 属性的属性特性:
属性 | 说明 | 备注 |
---|---|---|
writable | true | 如果设置为false,该属性值将不能被修改 |
enumerable | false | 如果设置为false,删除或更改任何属性都将会失败。 |
configurable | false | 如果设置为 true ,属性可以通过迭代器for或for...in进行迭代。 |
let fruits = [];
fruits.push('banana', 'apple', 'peach');
console.log(fruits.length);
// 3
fruits[5] = 'mango';
console.log(fruits[5]);
// 'mango'
console.log(Object.keys(fruits));
// ['0', '1', '2', '5']
console.log(fruits.length);
// 6
//减少length属性会删除元素
fruits.length = 2;
console.log(Object.keys(fruits));
// ['0', '1']
console.log(fruits.length);
// 2
Array.prototype
Array.prototype 属性表示 Array 构造函数的原型,并允许向所有Array对象添加新的属性和方法。
Array实例继承自 Array.prototype 。与所有构造函数一样,可以更改构造函数的原型对象,以对所有 Array 实例进行更改。例如,可以添加新方法和属性以扩展所有Array对象。这用于 polyfilling, 例如:
鲜为人知的事实:Array.prototype 本身也是一个 Array。
Array.isArray(Array.prototype);
// true
- Array.prototype 属性
属性 | 说明 |
---|---|
writable | false |
enumerable | false |
configurable | false |
- Array.prototype.constructor
所有的数组实例都继承了这个属性,它的值就是 Array,表明了所有的数组都是由 Array 构造出来的。
- Array.prototype.length
上面说了,因为 Array.prototype 也是个数组,所以它也有 length 属性,这个值为 0,因为它是个空数组。
会改变自身的方法
下面的这些方法会改变调用它们的对象自身的值:
- Array.prototype.copyWithin()
在数组内部,将一段元素序列拷贝到另一段元素序列上,覆盖原有的值。
- Array.prototype.fill()
将数组中指定区间的所有元素的值,都替换成某个固定的值。
- Array.prototype.pop()
删除数组的最后一个元素,并返回这个元素。
- Array.prototype.push()
在数组的末尾增加一个或多个元素,并返回数组的新长度。
- Array.prototype.reverse()
颠倒数组中元素的排列顺序,即原先的第一个变为最后一个,原先的最后一个变为第一个。
- Array.prototype.shift()
删除数组的第一个元素,并返回这个元素。
- Array.prototype.sort()
对数组元素进行排序,并返回当前数组。
- Array.prototype.splice()
在任意的位置给数组添加或删除任意个元素。
- Array.prototype.unshift()
在数组的开头增加一个或多个元素,并返回数组的新长度。
不会改变自身的方法
下面的这些方法绝对不会改变调用它们的对象的值,只会返回一个新的数组或者返回一个其它的期望值。
- Array.prototype.concat()
返回一个由当前数组和其它若干个数组或者若干个非数组值组合而成的新数组。
- Array.prototype.includes()
判断当前数组是否包含某指定的值,如果是返回 true,否则返回 false。
- Array.prototype.join()
连接所有数组元素组成一个字符串。
- Array.prototype.slice()
抽取当前数组中的一段元素组合成一个新数组。
- Array.prototype.toSource()
返回一个表示当前数组字面量的字符串。遮蔽了原型链上的 Object.prototype.toSource() 方法。
- Array.prototype.toString()
返回一个由所有数组元素组合而成的字符串。遮蔽了原型链上的 Object.prototype.toString() 方法。
- Array.prototype.toLocaleString()
返回一个由所有数组元素组合而成的本地化后的字符串。遮蔽了原型链上的 Object.prototype.toLocaleString() 方法。
- Array.prototype.indexOf()
返回数组中第一个与指定值相等的元素的索引,如果找不到这样的元素,则返回 -1。
- Array.prototype.lastIndexOf()
返回数组中最后一个(从右边数第一个)与指定值相等的元素的索引,如果找不到这样的元素,则返回 -1。
遍历方法
在下面的众多遍历方法中,有很多方法都需要指定一个回调函数作为参数。在每一个数组元素都分别执行完回调函数之前,数组的length属性会被缓存在某个地方,所以,如果你在回调函数中为当前数组添加了新的元素,那么那些新添加的元素是不会被遍历到的。此外,如果在回调函数中对当前数组进行了其它修改,比如改变某个元素的值或者删掉某个元素,那么随后的遍历操作可能会受到未预期的影响。总之,不要尝试在遍历过程中对原数组进行任何修改,虽然规范对这样的操作进行了详细的定义,但为了可读性和可维护性,请不要这样做。
- Array.prototype.forEach()
为数组中的每个元素执行一次回调函数。
- Array.prototype.entries()
返回一个数组迭代器对象,该迭代器会包含所有数组元素的键值对。
- Array.prototype.every()
如果数组中的每个元素都满足测试函数,则返回 true,否则返回 false。
- Array.prototype.some()
如果数组中至少有一个元素满足测试函数,则返回 true,否则返回 false。
- Array.prototype.filter()
将所有在过滤函数中返回 true 的数组元素放进一个新数组中并返回。
- Array.prototype.find()
找到第一个满足测试函数的元素并返回那个元素的值,如果找不到,则返回 undefined。
- Array.prototype.findIndex()
找到第一个满足测试函数的元素并返回那个元素的索引,如果找不到,则返回 -1。
- Array.prototype.keys()
返回一个数组迭代器对象,该迭代器会包含所有数组元素的键。
- Array.prototype.map()
返回一个由回调函数的返回值组成的新数组。
- Array.prototype.reduce()
从左到右为每个数组元素执行一次回调函数,并把上次回调函数的返回值放在一个暂存器中传给下次回调函数,并返回最后一次回调函数的返回值。
- Array.prototype.reduceRight()
从右到左为每个数组元素执行一次回调函数,并把上次回调函数的返回值放在一个暂存器中传给下次回调函数,并返回最后一次回调函数的返回值。
- Array.prototype.values()
返回一个数组迭代器对象,该迭代器会包含所有数组元素的值。
- Array.prototype[@@iterator]()
和上面的 values() 方法是同一个函数。
通用方法节
在 JavaScript 中,很多的数组方法被故意设计成是通用的。也就是说,那些看起来像是数组的对象(类数组对象),即拥有一个 length 属性,以及对应的索引属性(也就是数字类型的属性,比如 obj[5])的非数组对象也是可以调用那些数组方法的。其中一些数组方法,比如说 join 方法,它们只会单纯的读取当前对象的 length 属性和索性属性的值,并不会尝试去改变这些属性的值。而另外一些数组方法,比如说 reverse 方法,它们会尝试修改那些属性的值,因此,如果当前对象是个 String 对象,那么这些方法在执行时就会报错,因为字符串对象的 length 属性和索引属性都是只读的。
数组方法
Array.from()
Array.from()方法从一个类似数组或可迭代对象中创建一个新的数组实例。
let arr= Array.from('Array')
console.log(arr);
// ["A", "r", "r", "a", "y"]
console.log(Array.from([1, 2, 3], x => x*x));
// [1, 4, 9]
Array.from() 可以通过以下方式来创建数组对象:
- 伪数组对象(拥有一个length属性和若干索引属性的任意对象)
- 可迭代对象(可以获取对象中的元素,如 Map和 Set 等)
Array.from() 方法有一个可选参数
mapFn,让你可以在最后生成的数组上再执行一次 map 方法后再返回。也就是说 Array.from(obj, mapFn, thisArg) 就相当于 Array.from(obj).map(mapFn, thisArg), 除非创建的不是可用的中间数组。 这对一些数组的子类,如 typed arrays 来说很重要, 因为中间数组的值在调用 map() 时需要是适当的类型。
from() 的 length 属性为 1 ,即Array.from.length = 1。
在 ES2015 中, Class 语法允许我们为内置类型(比如 Array)和自定义类新建子类(比如叫 SubArray)。这些子类也会继承父类的静态方法,比如 SubArray.from(),调用该方法后会返回子类 SubArray 的一个实例,而不是 Array 的实例。
数组去重
function combine(){
let arr = [].concat.apply([], arguments); //没有去重复的新数组
return Array.from(new Set(arr));
}
var m = [1, 2, 2], n = [2,3,3];
console.log(combine(m,n)); // [1, 2, 3]
Array.isArray()
Array.isArray() 用于确定传递的值是否是一个 Array。
// 下面的函数调用都返回 true
Array.isArray([]);
Array.isArray([1]);
Array.isArray(new Array());
// 鲜为人知的事实:其实 Array.prototype 也是一个数组。
Array.isArray(Array.prototype);
// 下面的函数调用都返回 false
Array.isArray();
Array.isArray({});
Array.isArray(null);
Array.isArray(undefined);
Array.isArray(17);
Array.isArray('Array');
Array.isArray(true);
Array.isArray(false);
Array.isArray({ __proto__: Array.prototype });
instanceof 和 isArray
当检测Array实例时, Array.isArray 优于 instanceof,因为Array.isArray能检测iframes.
Array.of()
Array.of() 方法创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型。
Array.of() 和 Array 构造函数之间的区别在于处理整数参数:Array.of(7) 创建一个具有单个元素 7 的数组,而 Array(7) 创建一个长度为7的空数组(注意:这是指一个有7个空位的数组,而不是由7个undefined组成的数组)
Array.of(7); // [7]
Array.of(1, 2, 3); // [1, 2, 3]
Array(7); // [ , , , , , , ]
Array(1, 2, 3); // [1, 2, 3]
Array.concat()
concat() 方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组
Array.copyWithin()
copyWithin() 方法浅复制数组的一部分到同一数组中的另一个位置,并返回它,而不修改其大小
arr.copyWithin(target[, start[, end]])
- target
0 为基底的索引,复制序列到该位置。如果是负数,target 将从末尾开始计算。
如果 target 大于等于 arr.length,将会不发生拷贝。如果 target 在 start 之后,复制的序列将被修改以符合 arr.length。
- start
0 为基底的索引,开始复制元素的起始位置。如果是负数,start 将从末尾开始计算。
如果 start 被忽略,copyWithin 将会从0开始复制。
- end
0 为基底的索引,开始复制元素的结束位置。copyWithin 将会拷贝到该位置,但不包括 end 这个位置的元素。如果是负数, end 将从末尾开始计算。
如果 end 被忽略,copyWithin 将会复制到 arr.length。
[1, 2, 3, 4, 5].copyWithin(-2);
// [1, 2, 3, 1, 2]
[1, 2, 3, 4, 5].copyWithin(0, 3);
// [4, 5, 3, 4, 5]
[1, 2, 3, 4, 5].copyWithin(0, 3, 4);
// [4, 2, 3, 4, 5]
[1, 2, 3, 4, 5].copyWithin(-2, -3, -1);
// [1, 2, 3, 3, 4]
[].copyWithin.call({length: 5, 3: 1}, 0, 3);
({0:undefined,1:undefined,2:undefined,3: 1,4:undefined,5:undefined,length: 5}).copyWithin(0,3,5);
结果为:
{0:1,1:undefined,2:undefined,3: 1,4:undefined,5:undefined,length: 5};
也就是
{0:1,3:1,length:5}
// {0: 1, 3: 1, length: 5}
// ES2015 Typed Arrays are subclasses of Array
var i32a = new Int32Array([1, 2, 3, 4, 5]);
i32a.copyWithin(0, 2);
// Int32Array [3, 4, 5, 4, 5]
// On platforms that are not yet ES2015 compliant:
[].copyWithin.call(new Int32Array([1, 2, 3, 4, 5]), 0, 3, 4);
// Int32Array [4, 2, 3, 4, 5]
参数target,start和end 必须为整数。
如果start为负,则其指定的索引位置等同于length+start,length为数组的长度。end也是如此。
copyWithin方法不要求其this值必须是一个数组对象;除此之外,copyWithin是一个可变方法,它可以改变this对象本身,并且返回它,而不仅仅是它的拷贝。
copyWithin 就像 C 和 C++ 的 memcpy 函数一样,且它是用来移动 Array 或者 TypedArray 数据的一个高性能的方法。复制以及粘贴序列这两者是为一体的操作;即使复制和粘贴区域重叠,粘贴的序列也会有拷贝来的值。
copyWithin 函数是设计为通用的,其不要求其 this 值必须是一个数组对象。
The copyWithin 是一个可变方法,它不会改变 this 的 length,但是会改变 this 本身的内容,且需要时会创建新的属性。
Array.entries()
entries() 方法返回一个新的Array Iterator对象,该对象包含数组中每个索引的键/值对。
一个新的 Array 迭代器对象。Array Iterator是对象,它的原型(__proto__:Array Iterator)上有一个next方法,可用用于遍历迭代器取得原数组的[key,value]。
var arr = ['a', 'b', 'c'];
var iteratorArr = array1.entries();
console.log(iteratorArr.next().value);
// expected output: Array [0, "a"]
console.log(iteratorArr.next().value);
// expected output: Array [1, "b"]
- iterator.next方法
var arr = ["a", "b", "c"];
var iter = arr.entries();
var a = [];
// for(var i=0; i< arr.length; i++){ // 实际使用的是这个
for(var i=0; i< arr.length+1; i++){ // 注意,是length+1,比数组的长度大
var tem = iter.next(); // 每次迭代时更新next
console.log(tem.done); // 这里可以看到更新后的done都是false
if(tem.done !== true){ // 遍历迭代器结束done才是true
console.log(tem.value);
a[i]=tem.value;
}
}
console.log(a); // 遍历完毕,输出next.value的数组
- 二维数组排序
function sortArr(arr) {
var goNext = true;
var entries = arr.entries();
while (goNext) {
var result = entries.next();
if (result.done !== true) {
result.value[1].sort((a, b) => a - b);
goNext = true;
} else {
goNext = false;
}
}
return arr;
}
var arr = [[1,34],[456,2,3,44,234],[4567,1,4,5,6],[34,78,23,1]];
sortArr(arr);
/*(4) [Array(2), Array(5), Array(5), Array(4)]
0:(2) [1, 34]
1:(5) [2, 3, 44, 234, 456]
2:(5) [1, 4, 5, 6, 4567]
3:(4) [1, 23, 34, 78]
length:4
__proto__:Array(0)
*/
- 使用 for...of循环
var arr = ["a", "b", "c"];
var iterator = arr.entries();
// undefined
for (let e of iterator) {
console.log(e);
}
// [0, "a"]
// [1, "b"]
// [2, "c"]
Array.every()
every() 方法测试数组的所有元素是否都通过了指定函数的测试
function isBelowThreshold(currentValue) {
return currentValue < 40;
}
var array1 = [1, 30, 39, 29, 10, 13];
console.log(array1.every(isBelowThreshold));
// expected output: true
function isBigEnough(element, index, array) {
return (element >= 10);
}
var passed = [12, 5, 8, 130, 44].every(isBigEnough);
// passed is false
passed = [12, 54, 18, 130, 44].every(isBigEnough);
// passed is true
- every 方法为数组中的每个元素执行一次 callback 函数,直到它找到一个使 callback 返回 false(表示可转换为布尔值 false 的值)的元素。如果发现了一个这样的元素,every 方法将会立即返回 false。否则,callback 为每一个元素返回 true,every 就会返回 true。callback 只会为那些已经被赋值的索引调用。不会为那些被删除或从来没被赋值的索引调用。
- callback 被调用时传入三个参数:元素值,元素的索引,原数组。
如果为 every 提供一个 thisArg 参数,则该参数为调用 callback 时的 this 值。如果省略该参数,则 callback 被调用时的 this 值,在非严格模式下为全局对象,在严格模式下传入 undefined。
- every 不会改变原数组。
- every 遍历的元素范围在第一次调用 callback 之前就已确定了。在调用 every 之后添加到数组中的元素不会被 callback 访问到。如果数组中存在的元素被更改,则他们传入 callback 的值是 every 访问到他们那一刻的值。那些被删除的元素或从来未被赋值的元素将不会被访问到。
- every 和数学中的"所有"类似,当所有的元素都符合条件才返回true。另外,空数组也是返回true。(空数组中所有元素都符合给定的条件,注:因为空数组没有元素)。
Array.fill()
fill() 方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。
arr.fill(value,[start, end])
[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]
[1, 2, 3].fill(4, 1, 1); // [1, 2, 3]
[1, 2, 3].fill(4, 3, 3); // [1, 2, 3]
[1, 2, 3].fill(4, -3, -2); // [4, 2, 3]
[1, 2, 3].fill(4, NaN, NaN); // [1, 2, 3]
[1, 2, 3].fill(4, 3, 5); // [1, 2, 3]
Array(3).fill(4); // [4, 4, 4]
[].fill.call({ length: 3 }, 4); // {0: 4, 1: 4, 2: 4, length: 3}
// Objects by reference.
var arr = Array(3).fill({}) // [{}, {}, {}];
arr[0].hi = "hi"; // [{ hi: "hi" }, { hi: "hi" }, { hi: "hi" }]
- fill 方法接受三个参数 value, start 以及 end. start 和 end 参数是可选的, 其默认值分别为 0 和 this 对象的 length 属性值。
- 如果 start 是个负数, 则开始索引会被自动计算成为 length+start, 其中 length 是 this 对象的 length 属性值。如果 end 是个负数, 则结束索引会被自动计算成为 length+end。
- fill 方法故意被设计成通用方法, 该方法不要求 this 是数组对象。
- fill 方法是个可变方法, 它会改变调用它的 this 对象本身, 然后返回它, 而并不是返回一个副本。
- 当一个对象被传递给 fill方法的时候, 填充数组的是这个对象的引用。
Array.filter()
filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。
- filter 为数组中的每个元素调用一次 callback 函数,并利用所有使得 callback 返回 true 或 等价于 true 的值 的元素创建一个新数组。callback 只会在已经赋值的索引上被调用,对于那些已经被删除或者从未被赋值的索引不会被调用。那些没有通过 callback 测试的元素会被跳过,不会被包含在新数组中。
- callback 被调用时传入三个参数:
1.元素的值
2.元素的索引
3.被遍历的数组
- 如果为 filter 提供一个 thisArg 参数,则它会被作为 callback 被调用时的 this 值。否则,callback 的 this 值在非严格模式下将是全局对象,严格模式下为 undefined。
- callback 最终观察到的this值是根据通常函数所看到的 "this"的规则确定的。
- filter 不会改变原数组,它返回过滤后的新数组。
- filter 遍历的元素范围在第一次调用 callback 之前就已经确定了。在调用 filter 之后被添加到数组中的元素不会被 filter 遍历到。如果已经存在的元素被改变了,则他们传入 callback 的值是 filter 遍历到它们那一刻的值。被删除或从来未被赋值的元素不会被遍历
- 过滤JSON中的无效条目
var arr = [
{ id: 15 },
{ id: -1 },
{ id: 0 },
{ id: 3 },
{ id: 12.2 },
{ },
{ id: null },
{ id: NaN },
{ id: 'undefined' }
];
var invalidEntries = 0;
function isNumber(obj) {
return obj !== undefined && typeof(obj) === 'number' && !isNaN(obj);
}
function filterByID(item) {
if (isNumber(item.id) && item.id !== 0) {
return true;
}
invalidEntries++;
return false;
}
var arrByID = arr.filter(filterByID);
console.log('Filtered Array\n', arrByID);
// Filtered Array
// [{ id: 15 }, { id: -1 }, { id: 3 }, { id: 12.2 }]
console.log('Number of Invalid Entries = ', invalidEntries);
// Number of Invalid Entries = 5
- 搜索
const fruits = ['apple', 'banana', 'grapes', 'mango', 'orange'];
/**
* Array filters items based on search criteria (query)
*/
const filterItems = (query) => {
return fruits.filter((el) =>
el.toLowerCase().indexOf(query.toLowerCase()) > -1
);
}
console.log(filterItems('ap')); // ['apple', 'grapes']
console.log(filterItems('an')); // ['banana', 'mango', 'orange']
Array.find()
find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。
如果你需要找到一个元素的位置或者一个元素是否存在于数组中,使用Array.prototype.indexOf() 或 Array.prototype.includes()。
- 用对象的属性查找数组里的对象
var inventory = [
{name: 'apples', quantity: 2},
{name: 'bananas', quantity: 0},
{name: 'cherries', quantity: 5}
];
function findCherries(fruit) {
return fruit.name === 'cherries';
}
console.log(inventory.find(findCherries)); // { name: 'cherries', quantity: 5 }
寻
- 寻找质数
function isPrime(element, index, array) {
var start = 2;
while (start <= Math.sqrt(element)) {
if (element % start++ < 1) {
return false;
}
}
return element > 1;
}
console.log([4, 6, 8, 12].find(isPrime)); // undefined, not found
console.log([4, 5, 8, 12].find(isPrime)); // 5
Array.findIndex()
findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。否则返回-1。
function isPrime(element, index, array) {
var start = 2;
while (start <= Math.sqrt(element)) {
if (element % start++ < 1) {
return false;
}
}
return element > 1;
}
console.log([4, 6, 8, 12].findIndex(isPrime)); // -1, not found
console.log([4, 6, 7, 12].findIndex(isPrime)); // 2
Array.forEach()
forEach() 方法对数组的每个元素执行一次提供的函数
//<!--复制对象的函数-->
function copy(obj) {
var copy = Object.create(Object.getPrototypeOf(obj));
var propNames = Object.getOwnPropertyNames(obj);
propNames.forEach(function(name) {
var desc = Object.getOwnPropertyDescriptor(obj, name);
Object.defineProperty(copy, name, desc);
});
return copy;
}
var obj1 = { a: 1, b: 2 };
var obj2 = copy(obj1); // obj2 looks like obj1 now
- 如果数组在迭代时被修改了,则其他元素会被跳过。节
下面的例子输出"one", "two", "four"。当到达包含值"two"的项时,整个数组的第一个项被移除了,这导致所有剩下的项上移一个位置。因为元素 "four"现在在数组更前的位置,"three"会被跳过。 forEach()不会在迭代之前创建数组的副本
var words = ["one", "two", "three", "four"];
words.forEach(function(word) {
console.log(word);
if (word === "two") {
words.shift();
}
});
// one
// two
// four
Array.includes()
includes() 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回false。
[1, 2, 3].includes(2); // true
[1, 2, 3].includes(4); // false
- fromIndex 大于等于数组长度节
如果fromIndex 大于等于数组长度 ,则返回 false 。该数组不会被搜索
var arr = ['a', 'b', 'c'];
arr.includes('c', 3); //false
arr.includes('c', 100); // false
- includes() 作为一个通用方法节
includes() 方法有意设计为通用方法。它不要求this值是数组对象,所以它可以被用于其他类型的对象 (比如类数组对象)。下面的例子展示了 在函数的arguments对象上调用的includes() 方法。
(function() {
console.log([].includes.call(arguments, 'a')); // true
console.log([].includes.call(arguments, 'd')); // false
})('a','b','c');
Array.indexOf()
indexOf()方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1。
arr.indexOf(searchElement)
arr.indexOf(searchElement, fromIndex = 0)
- 找出指定元素的所有索引位置
var indices = [];
var array = ['a', 'b', 'a', 'c', 'a', 'd'];
var element = 'a';
var idx = array.indexOf(element);
while (idx != -1) {
indices.push(idx);
idx = array.indexOf(element, idx + 1);
}
console.log(indices);
// [0, 2, 4]
Array.join()
join() 方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。
str = arr.join()
// 默认为 ","
str = arr.join("")
// 分隔符 === 空字符串 ""
str = arr.join(separator)
// 分隔符
Array.keys()
var array1 = ['a', 'b', 'c'];
var iterator = array1.keys();
for (let key of iterator) {
console.log(key); // expected output: 0 1 2
}
- 会包含没有对应元素的索引
var arr = ["a", , "c"];
var sparseKeys = Object.keys(arr);
var denseKeys = [...arr.keys()];
console.log(sparseKeys); // ['0', '2']
console.log(denseKeys); // [0, 1, 2]
Array.lastIndexOf()
lastIndexOf() 方法返回指定元素(也即有效的 JavaScript 值或变量)在数组中的最后一个的索引,如果不存在则返回 -1。从数组的后面向前查找,从 fromIndex 处开始
arr.lastIndexOf(searchElement, fromIndex = arr.length - 1)
从此位置开始逆向查找。默认为数组的长度减 1,即整个数组都被查找。如果该值大于或等于数组的长度,则整个数组会被查找。如果为负值,将其视为从数组末尾向前的偏移。即使该值为负,数组仍然会被从后向前查找。如果该值为负时,其绝对值大于数组长度,则方法返回 -1,即数组不会被查找。。
Array.map()
map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
var kvArray = [{key: 1, value: 10},
{key: 2, value: 20},
{key: 3, value: 30}];
var reformattedArray = kvArray.map(function(obj) {
var rObj = {};
rObj[obj.key] = obj.value;
return rObj;
});
// reformattedArray 数组为: [{1: 10}, {2: 20}, {3: 30}],
// kvArray 数组未被修改:
// [{key: 1, value: 10},
// {key: 2, value: 20},
// {key: 3, value: 30}]
Array.pop()
pop()方法从数组中删除最后一个元素,并返回该元素的值。此方法更改数组的长度。
let myFish = ["angel", "clown", "mandarin", "surgeon"];
let popped = myFish.pop();
console.log(myFish);
// ["angel", "clown", "mandarin"]
console.log(popped);
// surgeon
Array.push()
push() 方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度
- push 方法有意具有通用性。该方法和 call() 或 apply() 一起使用时,可应用在类似数组的对象上。push 方法根据 length 属性来决定从哪里开始插入给定的值。如果 length 不能被转成一个数值,则插入的元素索引为 0,包括 length 不存在时。当 length 不存在时,将会创建它。
Array.reduce()
reduce() 方法对数组中的每个元素执行一个提供的reducer函数(升序执行),将其结果汇总为单个返回值
const array1 = [1, 2, 3, 4];
const reducer = (accumulator, currentValue) => accumulator + currentValue;
// 1 + 2 + 3 + 4
console.log(array1.reduce(reducer));
// expected output: 10
// 5 + 1 + 2 + 3 + 4
console.log(array1.reduce(reducer, 5));
// expected output: 15
reducer 函数接收4个参数:
Accumulator (acc) (累计器)
Current Value (cur) (当前值)
Current Index (idx) (当前索引)
Source Array (src) (源数组)
您的 reducer 函数的返回值分配给累计器,该返回值在数组的每个迭代中被记住,并最后成为最终的单个结果值。
var sum = [0, 1, 2, 3].reduce(function (accumulator, currentValue) {
return accumulator + currentValue;
}, 0);
// 和为 6
var initialValue = 0;
var sum = [{x: 1}, {x:2}, {x:3}].reduce(function (accumulator, currentValue) {
return accumulator + currentValue.x;
},initialValue)
console.log(sum) // logs 6
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(
function(a, b) {
return a.concat(b);
},
[]
);
// flattened is [0, 1, 2, 3, 4, 5]
var people = [
{ name: 'Alice', age: 21 },
{ name: 'Max', age: 20 },
{ name: 'Jane', age: 20 }
];
function groupBy(objectArray, property) {
return objectArray.reduce(function (acc, obj) {
var key = obj[property];
if (!acc[key]) {
acc[key] = [];
}
acc[key].push(obj);
return acc;
}, {});
}
var groupedPeople = groupBy(people, 'age');
// groupedPeople is:
// {
// 20: [
// { name: 'Max', age: 20 },
// { name: 'Jane', age: 20 }
// ],
// 21: [{ name: 'Alice', age: 21 }]
// }
let arr = [1,2,1,2,3,5,4,5,3,4,4,4,4];
let result = arr.sort().reduce((init, current)=>{
if(init.length===0 || init[init.length-1]!==current){
init.push(current);
}
return init;
}, []);
console.log(result); //[1,2,3,4,5]
Array.reduceRight()
reduceRight() 方法接受一个函数作为累加器(accumulator)和数组的每个值(从右到左)将其减少为单个值
reduceRight 为数组中每个元素调用一次 callback 回调函数,但是数组中被删除的索引或从未被赋值的索引会跳过。回调函数接受四个参数:初始值(或上次调用回调的返回值)、当前元素值、当前索引,以及调用 reduce 的数组
var a = ['1', '2', '3', '4', '5'];
var left = a.reduce(function(prev, cur) { return prev + cur; });
var right = a.reduceRight(function(prev, cur) { return prev + cur; });
console.log(left); // "12345"
console.log(right); // "54321"
Array.reverse()
reverse() 方法将数组中元素的位置颠倒。
var myArray = ['one', 'two', 'three'];
myArray.reverse();
console.log(myArray) // ['three', 'two', 'one']
Array.shift()
shift() 方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度
shift 方法移除索引为 0 的元素(即第一个元素),并返回被移除的元素,其他元素的索引值随之减 1。如果 length 属性的值为 0 (长度为 0),则返回 undefined。
shift 方法并不局限于数组:这个方法能够通过 call 或 apply 方法作用于类似数组的对象上。但是对于没有 length 属性(从0开始的一系列连续的数字属性的最后一个)的对象,调用该方法可能没有任何意义。
let myFish = ['angel', 'clown', 'mandarin', 'surgeon'];
console.log('调用 shift 之前: ' + myFish);
// "调用 shift 之前: angel,clown,mandarin,surgeon"
var shifted = myFish.shift();
console.log('调用 shift 之后: ' + myFish);
// "调用 shift 之后: clown,mandarin,surgeon"
console.log('被删除的元素: ' + shifted);
// "被删除的元素: angel"
Array.slice()
slice() 方法返回一个新的数组对象,这一对象是一个由 begin和 end(不包括end)决定的原数组的浅拷贝。原始数组不会被改变。
arr.slice();
// [0, end]
arr.slice(begin);
// [begin, end]
arr.slice(begin, end);
// [begin, end)
Array.some()
some() 方法测试数组中的某些元素是否通过由提供的函数实现的测试
some() 为数组中的每一个元素执行一次 callback 函数,直到找到一个使得 callback 返回一个“真值”(即可转换为布尔值 true 的值)。如果找到了这样一个值,some() 将会立即返回 true。否则,some() 返回 false。callback 只会在那些”有值“的索引上被调用,不会在那些被删除或从来未被赋值的索引上调用。
callback 被调用时传入三个参数:元素的值,元素的索引,被遍历的数组。
将会把它传给被调用的 callback,作为 this 值。否则,在非严格模式下将会是全局对象,严格模式下是 undefined。
some() 被调用时不会改变数组。
some() 遍历的元素的范围在第一次调用 callback. 时就已经确定了。在调用 some() 后被添加到数组中的值不会被 callback 访问到。如果数组中存在且还未被访问到的元素被 callback 改变了,则其传递给 callback 的值是 some() 访问到它那一刻的值。
function isBiggerThan10(element, index, array) {
return element > 10;
}
[2, 5, 8, 1, 4].some(isBiggerThan10); // false
[12, 5, 8, 1, 4].some(isBiggerThan10); // true
Array.sort()
sort() 方法用原地算法对数组的元素进行排序,并返回数组。排序算法现在是稳定的。默认排序顺序是根据字符串Unicode码点。
Array.splice()
splice()方法通过删除现有元素和/或添加新元素来修改数组,并以数组返回原数组中被修改的内容。
var myFish = ["angel", "clown", "mandarin", "surgeon"];
//从第 2 位开始删除 0 个元素,插入 "drum"
var removed = myFish.splice(2, 0, "drum");
//运算后的 myFish:["angel", "clown", "drum", "mandarin", "surgeon"]
//被删除元素数组:[],没有元素被删除
Array.toLocaleString()
toLocaleString() 返回一个字符串表示数组中的元素。数组中的元素将使用各自的 toLocaleString 方法转成字符串,这些字符串将使用一个特定语言环境的字符串(例如一个逗号 ",")隔开。
var prices = ['¥7', 500, 8123, 12];
prices.toLocaleString('ja-JP', { style: 'currency', currency: 'JPY' });
// "¥7,¥500,¥8,123,¥12"
Array.toString()
Array.unshift()
unshift() 方法将一个或多个元素添加到数组的开头,并返回该数组的新长度。
Array.values()
values() 方法返回一个新的 Array Iterator 对象,该对象包含数组每个索引的值
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。