关于javascript:javascript基础之数组

31次阅读

共计 9215 个字符,预计需要花费 24 分钟才能阅读完成。

javascript 数组: 繁多变量存储多个值

数组每个值叫做一个元素,而每个元素在数组中有一个地位,以数字示意,称为索引。

  1. 数组是值的有序汇合
  2. 固定长度
  3. 能够寄存不同的数据结构
  4. 一段线性调配的内存.

罕用办法

属性 名称 阐明
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 函数

截取数组中的几个元素 组成新的数组

  1. slice(start,end)示意从下标 start 开始到下标 end(不包含 end)进行截取,失去的是一个新数组,不扭转原数组。
  2. 当 start 为负值时示意从倒数第几个元素开始往后截取
  3. 不填 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 返回值。

  1. 简略来说,该办法返回值是一个数组。
  2. 初始时,这个数组是空数组,该办法会通过回调函数遍历整个数组(指 Array 这个),
  3. 如果以后的元素返回值为 true(或者能够隐式转换为 true 的,比方一个长度大于 0 的字符串),
  4. 那么会将以后元素增加到被返回的数组中。

例如:[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);

  1. 和 filter 的区别在于,filter 是将原数组元素,选择性退出到新数组中。
  2. 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);

}

正文完
 0