共计 9215 个字符,预计需要花费 24 分钟才能阅读完成。
javascript 数组: 繁多变量存储多个值
数组每个值叫做一个元素,而每个元素在数组中有一个地位,以数字示意,称为索引。
- 数组是值的有序汇合
- 固定长度
- 能够寄存不同的数据结构
- 一段线性调配的内存.
罕用办法
属性 | 名称 | 阐明 |
---|---|---|
length | 长度办法 | 长度办法 |
名称 | 阐明 |
---|---|
concat() | 连贯两个或多个数组,并返回已连贯数组的正本。 |
copyWithin | 将数组中的数组元素复制到指定地位或从指定地位复制。 |
entries | 返回键 / 值对数组迭代对象。 |
every | 查看数组中的每个元素是否通过测试。 |
fill | 用动态值填充数组中的元素。 |
filter | 应用数组中通过测试的每个元素创立新数组。 |
find | 返回数组中第一个通过测试的元素的值。 |
findIndex | 返回数组中通过测试的第一个元素的索引。 |
forEach | 为每个数组元素调用函数。 |
from | 从对象创立数组。 |
includes | 查看数组是否蕴含指定的元素。 |
indexOf | 在数组中搜寻元素并返回其地位。 |
isArray | 查看对象是否为数组。 |
join | 将数组的所有元素连接成一个字符串。 |
keys | 返回 Array Iteration 对象,蕴含原始数组的键. |
lastIndexOf | 在数组中搜寻元素,从开端开始,并返回其地位。 |
map | 应用为每个数组元素调用函数的后果创立新数组。 |
pop | 删除数组的最初一个元素,并返回该元素。 |
push | 将新元素增加到数组的开端,并返回新的长度。 |
reduce | 将数组的值减为单个值(从左到右)。 |
reduceRight | 将数组的值减为单个值(从右到左)。 |
reverse | 反转数组中元素的程序。 |
shift | 删除数组的第一个元素,并返回该元素。 |
slice | 抉择数组的一部分,并返回新数组。 |
some | 查看数组中的任何元素是否通过测试。 |
sort | 对数组的元素进行排序。 |
splice | 从数组中增加 / 删除元素。 |
toString | 将数组转换为字符串,并返回后果。 |
unshift | 将新元素增加到数组的结尾,并返回新的长度。 |
详解
slice 函数
截取数组中的几个元素 组成新的数组
- slice(start,end)示意从下标 start 开始到下标 end(不包含 end)进行截取,失去的是一个新数组,不扭转原数组。
- 当 start 为负值时示意从倒数第几个元素开始往后截取
- 不填 end 的话就示意从倒数第几个元素开始截取,始终截取到数组开端元素。
// 简略复制, 浅拷贝
var _array = [1,2,3,4,5]
var copyArray = _array.slice();
// 获取从 N 开始的子数组
// 心愿弹出数组的第一个元素并应用它,返回残余的数组,但心愿在不批改原始数组的状况下执行此操作。function useone (arr) {const usedItem = arr[0]
return arr.slice(1)
}
// 获取从开端 N 开始的子数组, 负索引使删除任意数量的元素变得简略
const sliceArr = _array.slice(-3)
console.log('sliceArr',sliceArr) //[3,4,5]
// 获取数组的前 n 个
const first4 = _array.slice(0, 4) // [1,2,3,4]
// 获取数组中某段子数组
function getSegement(arr, begin, length) {return arr.slice(begin, begin + length);
}
console.log(getSegement(_array,1,3)) // [2,3,4]
// 相似数组的对象转换
Array.prototype.slice.call(arguments)
// 批改数组中的特定索引
// slice 在函数上下文中一个弱小而常见的用法是替换数组中特定项的值。从实质上讲,这很简略,只须要调配新值,然而在函数世界中,不能批改原始数组。相同,能够将 slice 与扩大运算符一起应用,以返回一个雷同但对于要更新的索引的新数组:function replaceIdx(arr,index,newVal) {
return [...arr.slice(0,index),
newVal,
...arr.slice(index+1)
]
}
// 偏函数利用
var partial = function() {const fn = arguments[0];
const args = Array.prototype.slice.call(arguments, 1);
// Return a function that calls fn
return function() {var remainingArgs = Array.prototype.slice.call(arguments);
return fn.apply(this, args.concat(remainingArgs));
}
}
// 将任意长度多余的参数强制转换为数组
function myFunc(a, b) {const extraArgs = Array.prototype.slice.call(arguments, 2);
}
myFunc(1, 2, 3, 4, 5, 6, 7, 8) // 失去 a == 1,b === 2,extraArgs=== [3,4,5,6,7,8]
splice 函数
splice()办法有三个参数,别离示意从哪个下标开始,删几个元素。能够实现减少,删除,替换数组元素的性能。arr.splice(-5,5)示意从倒数第五个元素开始,删五个元素。奇妙的是该办法的返回值是删除的元素汇合。同时该办法扭转了原数组。原数组变成了除了删除的元素剩下的元素汇合。
var numbers = [1,2,3,'hello','javascript',33,'world', {"name":"wxh","age":33}];
// 复制数组
var _array = [];
console.log(numbers.splice(0,2,'a','b','c')) // [1, 2]
console.log(numbers) // ['a','b','c', 3,'hello','javascript',33,'world',{ name: 'wxh', age: 33} ]
forEach 函数
// 规范
forEach(callback[,thisArg])
// 简略示例
Array.forEach(function(item, index, array){// 回调函数内容}, args);
// 扩大
if (!Array.prototype.forEach) {Array.prototype.forEach = function (callback, thisArg) {for (var i = 0; i < this.length; i++) {
// 当 thisArg 为 undefined 时,JS 引擎会将 window 作为其调用者
if (this[i])
callback.call(thisArg, this[i], i, this);
}
}
}
filter 函数
3 个参数同 forEach,args 也同 forEach,惟一不同的是,函数有回调函数里有 return 返回值。
- 简略来说,该办法返回值是一个数组。
- 初始时,这个数组是空数组,该办法会通过回调函数遍历整个数组(指 Array 这个),
- 如果以后的元素返回值为 true(或者能够隐式转换为 true 的,比方一个长度大于 0 的字符串),
- 那么会将以后元素增加到被返回的数组中。
例如:[1, 2, 3],
回调函数的 return 是 item > 1,
当第一个元素 1 时,1>1 为 false,因而不会增加到返回的数组中,
而 2 和 3 >1 显然是 true,因而会被增加到数组中。最终,返回值是[2,3]。
// 规范
filter(callback[,thisArg])
// 简略示例
Array.filter(function(item, index, array){// 回调函数内容}, args);
// 扩大
if (!Array.prototype.filter) {Array.prototype.filter = function (callback, thisArg) {var temp = [];
for (var i = 0; i < this.length; i++) {if (this[i]) {if (callback.call(thisArg, this[i], i, this)) {
// 如果 callback 返回 true, 则该元素合乎过滤条件,将元素压入 temp 中
temp.push(this[i]);
}
}
}
return temp;
}
}
map 函数
3 个参数同 forEach,args 也同 forEach,惟一不同的是,函数有回调函数里有 return 返回值。
简略来说,该办法的返回值也是一个数组(类 filter);
- 和 filter 的区别在于,filter 是将原数组元素,选择性退出到新数组中。
- map 是将原数组的每个元素,进行解决后,放到新数组中。
例如:[1,2,3]作为原数组,map 回调函数内的代码为:
return item + 10;
那么就相当于将 1 +10 放到数组中,而后将 2 +10 放到数组中,再将 3 +10 放到数组中。
后果为:[11, 12, 13]
当然,也能够写更简单的逻辑,比方 if(item>3)时 +10,而后 else if(item>2)时 +5,否则 else -10
那么后果就是[-9, 7, 13]
// 规范
map(callback[,thisArg])
// 简略示例
Array.map(function(item, index, array){// 回调函数内容}, args);
// 扩大
if (!Array.prototype.map) {Array.prototype.map = function (callback, thisArg) {var temp = [];
for (var i = 0; i < this.length; i++) {if (this[i]) {var newItem = callback.call(thisArg, this[i], i, this);
temp[i] = newItem// 将 callback 返回的新元素压入 temp 中
}
}
return temp;
}
}
reduce 函数
首先看回调函数,他有四个参数,
item 是以后元素,别的中央写的是 currentValue 示意以后值,为了不便了解,我这里写 item 和下面对立格调
index 是以后元素的索引;
Array 是整个数组(能够通过这个批改源数组);
下面 3 个都很好了解。
第一个参数 previousValue 是外围。他示意上一次执行回调函数时的返回值。
例如,有数组 [1, 2, 3, 4]
当我遍历到第二个元素时,回调函数的 previousValue 的值是 1,item 的值为 2,
return 我写为:return previousValue + item
那么当遍历到第三个元素时,回调函数的 previousValue 的值则为 3(因为 1 +2),item 的值为 3
当遍历到第四个元素时,previous 的值则为 6(因为 3 +3),
最终 reduce 的返回值为 10(因为 6 +4)
那么问题来了,为什么没提到遍历第一个元素?
起因是,当 reduce 没有第二个参数时,遍历从数组的第二个元素开始,
第一次执行回调函数的 previousValue 的值是数组第一个元素的值
当 reduce 存在第二个参数时(哪怕是 null 或者 undefined),遍历都将从第一个元素开始;
第一次执行回调函数时(遍历第一个元素),previousValue 的值是第二个参数的值,而 item 是第一个元素的值
所以在应用的时候须要留神,如果须要执行和数组元素个数一样次数的回调函数,那么必须设置 reduce 的第二个参数;
如果不设置,那么回到函数次数执行的次数,将比数组元素个数少 1。
// 规范
reduce(callback[,initialValue])
// 简略示例
arr.reduce(function (previousValue, item, index, Array) {return xxx; //xxx 示意省略});
// 扩大
if (!Array.prototype.reduce) {Array.prototype.reduce = function (callback, initialValue) {var previousValue = initialValue || this[0];// 如果不指定 intialValue, 则默认为数组的第一个元素
// 如果不指定 initialValue(即第二个参数),i 从 1(第二个元素)开始遍历,否则就从 0(第一个元素)开始遍历
for (var i = initialValue ? 0 : 1; i < this.length; i++) {
//previousValue 累加每一次返回的后果
if (this[i])
previousValue = callback(previousValue, this[i], i, this.toString());
}
return previousValue;
}
}
reduceRight 函数
// 规范
reduceRight(callback[,initialValue])
// 简略示例
arr.reduceRight(function (previousValue, item, index, Array) {return xxx; //xxx 示意省略});
// 扩大
if (!Array.prototype.reduceRight) {Array.prototype.reduceRight = function (callback, initialValue) {var previousValue = initialValue || this[this.length - 1];// 如果不指定 intialValue, 则默认为数组的第一个元素
// 如果不指定 initialValue(即第二个参数),i 从 1(第二个元素)开始遍历,否则就从 0(第一个元素)开始遍历
for (var i = (initialValue ? this.length - 1 : this.length - 2); i > -1; i--) {
//previousValue 累加每一次返回的后果
if (this[i])
previousValue = callback(previousValue, this[i], i, this);
}
return previousValue;
}
}
every 函数
返回值是 true 或者 false
初始状况下是 true;
而后遍历数组,有一个不满足,则为 false,并且终止遍历过程。
回调函数的 this 仍然默认指向 window,或者是 every 的第二个参数。
空数组的 every 返回后果是 true。
// 规范
every(callback, thisArg);
// 简略示例
arr.every(function(item, index, array){return item > xx;});
if (!Array.prototype.every) {Array.prototype.every = function (callback, thisArg) {
var result = true;
for (var i = 0; i < this.length; i++) {if (this[i]) {if (!callback.call(thisArg ? thisArg : window, this[i], i, this)) {
result = false;
break;
}
}
}
return result; // 所有元素都符合条件,返回 true
}
}
indexOf 函数
用于查找第一个参数是否在数组中;
如果不在,返回 -1;
如果在,返回在数组中遇见的第一个的下标;
例如:[1,2,3,2].indexOf(2)的返回值是 1,尽管第二个和第四个元素都是,然而先遇见第二个,而第二个的下标是 1
如果 indexOf 有第二个参数,那么从数组中第二个参数所指向的下标地位开始往后找;
例如:[1,2,3,2].indexOf(2,2)的返回值是 3,因为开始下标是 2(即第三个元素 3),因而从第三个开始,遇见的第一个 2 的下标是 2;
判断时含第二个参数所指向的数组元素
// 规范
arr.indexOf(searchElement, fromIndex);
// 简略示例
[1,2,3].indexOf(2); //1(数组的第二个元素)[1,2,3].indexOf(4); //-1(未找到,留神,- 1 不是 false,隐式转换后他的值为 true)if (!Array.prototype.indexOf) {Array.prototype.indexOf = function (searchElement, fromIndex) {
var result = -1;
for (var i = fromIndex ? fromIndex : 0; i < this.length; i++) {if (this[i]) {if (searchElement === this[i]) {
result = i;
break;
}
}
}
return result; // 所有元素都符合条件,返回 true
}
}
lastIndexOf 函数
// 规范
arr.lastIndexOf(searchElement, fromIndex);
// 简略示例
[1,2,1].lastIndexOf(1); //2
[1,2,1].lastIndexOf(1, 1); //0
if (!Array.prototype.lastIndexOf) {Array.prototype.lastIndexOf = function (searchElement, fromIndex) {
var result = -1;
for (var i = (fromIndex ? fromIndex : this.length - 1); i > -1; i--) {if (this[i]) {if (searchElement === this[i]) {
result = i;
break;
}
}
}
return result; // 所有元素都符合条件,返回 true
}
}
from 函数
Array.from() 从类数组对象或者可迭代对象中创立一个新的数组实例。
console.log(Array.from([1,2,3],x=>x*x)); // 2,4,9
Array.isArray() 用来判断某个变量是否是一个数组对象。
console.log(Array.isArray(Array.from([1,2,3]))); // true
Array.of() 依据一组参数来创立新的数组实例,反对任意的参数数量和类型。
console.log(Array.of(1, 2, 3));// [1,2,3]
concat 函数
连贯两个或更多的数组,并返回后果
var arr = [1, 2, 3];
var arr2= arr.concat("4", "5", "6"); //["1", "2", "3", "4", "5", "6"];
join 函数
把数组的所有元素放入一个字符串并通过指定的分隔符进行分隔
arr.join("+"); //"1+2+3";
reverse 函数
反转数组中元素的程序。
arr.reverse();
console.log(arr); // [3, 2, 1];
sort 函数
数组排序 依照字符串的形式来排序。
toString 函数
把数组转换为字符串,并返回后果
find 函数
返回传入一个测试条件, 符合条件的数组第一个元素, 当数组中的元素在测试条件时返回 true 时, find() 返回符合条件的元素,之后的值不会再调用执行函数。如果没有符合条件的元素返回 undefined
const pets = [{ type: 'Dog', name: 'Max'},
{type: 'Cat', name: 'Karl'},
{type: 'Dog', name: 'Tommy'},
];
var pet = pets.find(pet => pet.type ==='Dog' && pet.name === 'Tommy');
console.log(pet); // {type: 'Dog', name: 'Tommy'}
some 函数
用于检测数组中的元素是否满足指定条件, 如果有一个元素满足条件,则表达式返回 true, 残余的元素不会再执行检测, 如果没有满足条件的元素,则返回 false。
let arr = [1, 2, 3, 4, 5]
console.log(arr.some(item => item === 2)); // true
// ES5 循环实现 some 办法
const selfSome = function (fn, context) {let arr = Array.prototype.slice.call(this) // 复制数组原型对象
// 空数组间接返回 false,数组的 every 办法则相同返回 true
if(!arr.length) return false
for (let i = 0; i < arr.length; i++) {if(!arr.hasOwnProperty(i)) continue;
let res = fn.call(context,arr[i],i,this)
if(res)return true
}
return false
}
// 挂载
Array.prototype.selfSome ||(Object.defineProperty(Array.prototype, 'selfSome', {
value: selfSome,
enumerable: false,
configurable: true,
writable: true
}))
console.log(arr.selfSome(item => item === 2)) // true
数组与字符串转换
var arr = ['wxh','cjk','dbt','cjk']
console.log(arr.join(",")) // 以 逗号 进行宰割
Array.from(new Set(arr)) // ['wxh','cjk','dbt'] // 数组去重
var str = "wxh,cjk,dbt"
console.log(str.split(","))
console.log(Array.from(str)) // ['w', 'x', 'h', ',',....]
数组与对象转换
let arrayLike = {
'0': 'wxh',
'1': 'cjk',
'2': 'dbt',
length: 3
};
// ES5 的写法
var arr1 = [].slice.call(arrayLike); // ['wxh', 'cjk', 'dbt']
// ES6 的写法
let arr2 = Array.from(arrayLike); // ['wxh', 'cjk', 'dbt']
// NodeList 对象
let arr3 = document.querySelectorAll('p');
Array.from(arr3).forEach(function (item) {console.log(item);
});
// arguments 对象
function foo() {var args = Array.from(arguments);
}