Array的操作方法
1. unshift()
arrayObject.unshift(newelement1,newelement2,....,newelementX)
- 向数组开头添加一个或多个元素,并返回新的长度
- 改变原数组
let arr = [1,2,3]
let len = arr.unshift(1)
console.log(len) // 4
console.log(arr) // [1, 1, 2, 3]
2. shift()
arrayObject.shift()
- 删除数组第一个元素,并返回删除的元素本身
- 如果数组为空,则不修改素组,返回undefined
- 改变原数组
let arr = [1,2,3]
console.log(arr.shift()) // 1
console.log(arr) // [2, 3]
3. push()
arrayObject.push(newelement1,newelement2,....,newelementX)
- 向数组末尾添加一个或多个元素,并返回新长度
- 改变原数组
let arr = [1,2,3]
console.log(arr.push(1,2)) // 5
console.log(arr) // [1, 2, 3, 1, 2]
4. pop()
arrayObject.pop()
- 删除数组最后一个元素,并返回删除元素本身
- 如果数组为空,则不修改数组,并返回undefined
- 改变原素组
let arr = [1,2,3]
console.log(arr.pop()) // 3
console.log(arr) // [1, 2]
console.log([].pop()) // undefined
5. concat()
arrayObject.concat(val1,val2,......,[val3])
数组和/或值,将被合并到一个新的数组中。如果省略了所有 valueN 参数,则 concat 会返回调用此方法的现存数组的一个浅拷贝 -MDN
- 合并多个数组/值,返回合并后的数组
- 不改变原数组
let arr1 = [1,2,3], arr2 = [4,5,6], arr3 = [7]
console.log(arr1.concat(arr2, arr3)) // [1, 2, 3, 4, 5, 6, 7]
console.log(arr1) // [1, 2, 3]
6. splice()
arrayObject.splice(index,howmany,item1,.....,itemX)
- 删除数组指定位置长度的元素,或添加一个、多个元素,返回删除元素
- 添加元素可选
- 改变原数组
let arr1 = [1,2,3]
console.log(arr1.splice(1,2)) // [2, 3]
console.log(arr1) // [1]
console.log(arr1.splice(1,0,2,3)) // []
console.log(arr1) // [1, 2, 3]
7. slice()
arrayObject.slice(start,end)
- 截取数组指定开始和结束下边的元素,并返回结果元素数组
- end可选
- 不改变原数组
let arr1 = [1,2,3]
console.log(arr1.slice(1, 2)) // [2]
console.log(arr1.slice(1)) // [2, 3]
console.log(arr1) // [1, 2, 3]
8. sort()
arrayObject.sort(sortby)
- 对数组进行排序,返回排序后的数组
- 改变原数组
let arr1 = [2,1,3]
console.log(arr1.sort()) // [1, 2, 3]
console.log(arr1) // [1, 2, 3]
!注意
由于sort()方法是分别调用元素的toString()方法,本质上是比较字符串,因而会出现以下情况
let arr1 = [3,10,2]
console.log(arr1.sort()) // [10, 2, 3]
console.log(arr1) // [10, 2, 3]
这是因为'10'和'2'会先比较'1',因而10在最前,改进方法如下,编写一个比较函数
- 想让第一个值靠前,则返回小于0的数,相等则返回0,靠后则返回大于0的数
let arr1 = [3,10,2]
console.log(arr1.sort(compare)) // [2, 3, 10]
console.log(arr1) // [2, 3, 10]
function compare(value1, value2) {
return value1 - value2
}
9. reverse()
arrayObject.reverse()
- 反转数组,返回反转后的数组
- 改变原数组
let arr1 = [1, 2, 3]
console.log(arr1.reverse()) // [3, 2, 1]
console.log(arr1) // [3, 2, 1]
10. join()
arrayObject.join(separator)
- 以指定字符分割数组,返回分割后的字符串
- 若参数不填,则默认以','为分割符
- 不改变原数组
let arr1 = [1,2,3]
console.log(arr1.join()) // 1,2,3
console.log(arr1.join('!')) // 1!2!3
console.log(arr1) // [1, 2, 3]
Array的遍历方法
1. forEach()
array.forEach(function(currentValue, index, arr), thisValue)
- 遍历数组每一个元素,并在回调函数中处理
- 不改变原数组
let arr = [1,2,3], newArr = []
arr.forEach(item => newArr.push(++item))
console.log(arr) // [1, 2, 3]
console.log(newArr) // [2, 3, 4]
2. map()
array.map(function(currentValue,index,arr), thisValue)
- 遍历数组每一项,并返回操作后的数组
- 不改变原数组
- thisValue 绑定回调函数的this上下文
let arr = [1,2,3], newArr = []
newArr = arr.map(function (item, index, array) {
console.log(this) // {a: 1}
return ++item
}, {a: 1})
console.log(arr) // [1, 2, 3]
console.log(newArr) // [2, 3, 4]
3. filter()
array.filter(function(currentValue,index,arr), thisValue)
- 遍历数组每一项,并在回调中处理,返回符合条件的新数组
- 不改变原数组
let arr = [1,2,3], newArr = []
newArr = arr.filter(item => item >=2)
console.log(arr) // [1, 2, 3]
console.log(newArr) // [2, 3]
4. every()
array.every(function(currentValue,index,arr), thisValue)
- 遍历数组每一项,通过回调判断是否符合条件
- 若有一项不符合,则返回false,不继续执行;若全部符合则返回true
- 不改变原数组
let arr = [1,2,3], newArr = []
let isTrue = arr.every(item => item > 0)
console.log(arr) // [1, 2, 3]
console.log(isTrue) // true
如何判断是否为Array
isArray()
let arr = [1, 2, 3]
Array.isArray(arr) // true
instanceof
- 原理:左侧被检测对象的原型链上是否包含右侧构造函数的prototype属性
let arr = [1, 2, 3]
arr instanceof Array // true
Object instanceof Object // true
Function instanceof Object // true
Object instanceof Function // true
constructor
- constructor 属性返回对象的构造函数, 数组对象的构造函数为Array
let arr = [1, 2, 3]
arr.constructor === Array // true
arr.constructor // ƒ Array() { [native code] }
不同对象的constructor
function f () {}
console.log([].constructor) // ƒ Array() { [native code] }
console.log({}.constructor) // ƒ Object() { [native code] }
console.log(f.constructor) // ƒ Function() { [native code] }
console.log((123).constructor) // ƒ Number() { [native code] }
console.log('123'.constructor) // ƒ String() { [native code] }
console.log(true.constructor) // ƒ Boolean() { [native code] }
手动实现Array的方法
Array.map()
本身用法:
Array.map(function(item, index, arr){}, thisValue)
- 返回处理后的新数组
- map本身接受两个参数,一个函数,一个对象上下文
- 函数内三个参数分别为:元素本身,元素下标、原数组
- 对象上下文的作用是绑定函数的this指向
实现原理:
Array.prototype.map = function (fn, context) {
let newArray = []
for(let i=0;i<this.length;i++){
// 通过call()来绑定回调函数的上下文
newArray.push(fn.call(context, this[i], i, this))
}
return newArray
}
- fn为回调函数,context为传入的对象上下文
- 我们给fn使用call()来绑定fn的上下文,call立即执行,并将执行结果push到新数组中
Array.filter()
本身用法:
Array.filter(function(item, index ,array){}, thisValue)
- 返回符合条件的新数组
- map本身接受两个参数,一个函数,一个对象上下文
- 函数内三个参数分别为:元素本身,元素下标、原数组
- 对象上下文的作用是绑定函数的this指向
实现原理:
Array.prototype.filter = function (fn, context) {
let newArray = []
for (let i=0;i<this.length;i++) {
if(fn.call(context, this[i], i, this)) {
newArray.push(this[i])
}
}
return newArray
}
- 因为fn.call(···)返回是布尔类型,所以要先进行判断,若为真则添加到新数组中