1、如何判斷數(shù)組是數(shù)組類型来庭?
-
Array.isArray() 最靠譜的判斷數(shù)組的方法
在調(diào)用這個方法之前重寫了Object.prototype.toString方法或修改constructor對象稍味,不影響判斷的結(jié)果
Object.prototype.toString = ()=>{ console.log('Hello Howard'); } const a = []; Array.isArray(a);//true a.constructor = b.constructor; Array.isArray(a);//true
兼容寫法
if (!Array.isArray) { Array.isArray = function(arg) { return Object.prototype.toString.call(arg) === '[object Array]'; }; }
-
驗證構(gòu)造函數(shù)
- 用instanceof判斷:判斷某個構(gòu)造函數(shù)的prototype屬性所指向的對象是否存在于要檢測對象的原型鏈上
object instanceof constructor const a = []; const b = {}; console.log(a instanceof Array);//true console.log(a instanceof Object);//true,在數(shù)組的原型鏈上也能找到 Object構(gòu)造函數(shù)
? 驗證不夠嚴格删咱。 即使對象創(chuàng)建時不是使用數(shù)組創(chuàng)建的杖小,但是只要原型鏈上有數(shù)組類型
function Test(){} Test.prototype = Array.prototype; let test = new Test(); test instanceof Array;//true
-
constructor:實例化的數(shù)組擁有一個constructor屬性,這個屬性指向生成這個數(shù)組的方法
obj.constructor == Array const a = []; console.log(a.constructor);//function Array(){ [native code] }
-
驗證原型對象
-
getPrototypeOf: 這是Object自帶的一個API碾阁,作用是獲取一個對象的原型對象
- Object.getPrototypeOf(obj) == Array.prototype
-
isPrototypeOf:每個對象都有一個isPrototypeOf的API输虱,繼承自O(shè)bject.prototype
- var bool = Array.prototype.isPrototypeOf(obj)
-
getPrototypeOf: 這是Object自帶的一個API碾阁,作用是獲取一個對象的原型對象
-
檢查內(nèi)部屬性class + call或apply
每個對象中記錄對象創(chuàng)建時使用的類型的屬性,一旦對象被創(chuàng)建脂凶,class屬性就無法被修改宪睹。獲得class的唯一的辦法就是調(diào)用Object.prototype中的toString()方法
const a = ['Hello','Howard']; Object.prototype.toString.call(a);//"[object Array]" Object.prototype.toString.apply(a);//"[object Array]"
2、數(shù)組與字符串
- 由數(shù)組轉(zhuǎn)換為字符串蚕钦,使用join亭病;
- 由字符串轉(zhuǎn)換為數(shù)組,使用split
// join - 由數(shù)組轉(zhuǎn)換為字符串嘶居,使用join
console.log(['Hello', 'World'].join(',')); // Hello,World
// split - 由字符串轉(zhuǎn)換為數(shù)組罪帖,使用split
console.log('Hello World'.split(' ')); // ["Hello", "World"]
3、查找元素
indexOf : arr.indexOf(searchElement[, fromIndex])
searchElement:需檢索的元素
fromIndex:可選整數(shù)參數(shù)邮屁,規(guī)定在數(shù)組中開始檢索的位置
// indexOf - 查找元素
console.log(['abc', 'bcd', 'cde'].indexOf('bcd')); // 1
4整袁、數(shù)組連接
使用concat之后會生成一個新的數(shù)組
var array1 = [1, 2, 3];
var array2 = [4, 5, 6];
var array3 = array1.concat(array2); // 實現(xiàn)數(shù)組連接之后,會創(chuàng)建出新的數(shù)組
console.log(array3);
5佑吝、類列表操作
push/pop/shift/unshift
var array = [2, 3, 4, 5]; // 添加到數(shù)組尾部
array.push(6);
console.log(array); // [2, 3, 4, 5, 6]
// 添加到數(shù)組頭部
array.unshift(1);
console.log(array); // [1, 2, 3, 4, 5, 6]
// 移除最后一個元素
var elementOfPop = array.pop();
console.log(elementOfPop); // 6
console.log(array); // [1, 2, 3, 4, 5]
// 移除第一個元素
var elementOfShift = array.shift();
console.log(elementOfShift); // 1
console.log(array); // [2, 3, 4, 5]
6坐昙、splice方法
主要兩個用途:
- 從數(shù)組中間位置添加和刪除元素
- 從原有數(shù)組中,獲取一個新數(shù)組
需提供如下參數(shù)
- 起始索引(也就是你希望開始添加元素的地方)
- 需要刪除的元素的個數(shù)或是提取的元素的個數(shù)(添加元素時該參數(shù)設(shè)置為0)
- 想要添加進數(shù)組的元素
var nums = [1, 2, 3, 7, 8, 9];
nums.splice(3, 0, 4, 5, 6);
console.log(nums); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
// 緊接著做刪除操作或者提取新的數(shù)組
var newnums = nums.splice(3, 4);
console.log(nums); // [1, 2, 3, 8, 9]
console.log(newnums); // [4, 5, 6, 7]
7芋忿、排序
reverse:數(shù)組反轉(zhuǎn)
// 反轉(zhuǎn)數(shù)組
var array = [1, 2, 3, 4, 5];
array.reverse();
console.log(array); // [5, 4, 3, 2, 1]
sort:按照字典順序?qū)υ剡M行排序民珍,在調(diào)用方法時傳入一個大小比較函數(shù)襟士,排序時盗飒,sort()方法將會根據(jù)該函數(shù)比較數(shù)組中兩個元素的大小
var compare = function(num1, num2) {
return num1 > num2;
};
nums.sort(compare);
console.log(nums); // [1, 2, 3, 4, 100, 200]
var objInArray = [
{
name: 'king',
pass: '123',
index: 2
},
{
name: 'king1',
pass: '234',
index: 1
}
];
// 對數(shù)組中的對象元素嚷量,根據(jù)index進行升序
var compare = function(o1, o2) {
return o1.index > o2.index;
};
objInArray.sort(compare);
console.log(objInArray[0].index < objInArray[1].index); // true
8、for of, for in 和 forEach用法及其區(qū)別
-
for in:用于遍歷數(shù)組或者對象的屬性
- 缺點:鍵名是字符串逆趣;會遍歷對象本身的所有可枚舉屬性和從它原型繼承而來的可枚舉屬性蝶溶,僅迭代對象本身的屬性,要結(jié)合hasOwnProperty()來使用宣渗;
let aArray = ['a',123,{a:'1',b:'2'}];
aArray.name = 'demo';
for(let index in aArray){
console.log(index); //0,1,2,name也被循環(huán)出來了
}
var obj = {
name:"echolun",
age:"24",
sex:"male"
},
objName=[], //用來裝對象屬性名
objVal=[]; //用來裝對象屬性值
Object.prototype.game="lastgame";
for(var i in obj){
if(obj.hasOwnProperty(i)) {
objName.push(i);
objVal.push(obj[i]);
}
}
console.log(objName,objVal);
}
- for of:可迭代對象(Array抖所,Map,Set痕囱,String田轧,TypedArray,arguments)上創(chuàng)建一個迭代循環(huán)
for(var value of aArray){
console.log(value); // 'a',123,{a:'1',b:'2'}
}
var student={
name:'wujunchuan',
age:22,
locate:{
country:'china',
city:'xiamen',
school:'XMUT'
}
}
for(var key of Object.keys(student)){
//使用Object.keys()方法獲取對象key的數(shù)組
console.log(key+": "+student[key]);
}
- for of 與 for in 區(qū)別
推薦在循環(huán)對象屬性的時候鞍恢,使用for...in,在遍歷數(shù)組的時候的時候使用for...of傻粘。
for...in循環(huán)出的是key,for...of循環(huán)出的是value
for...of是ES6新引入的特性帮掉。修復了ES5引入的for...in的不足
for...of不能循環(huán)普通的對象弦悉,需要通過和Object.keys()搭配使用
- forEach:用于遍歷數(shù)組,在運行途中無法跳出循環(huán)蟆炊,break和return不起作用稽莉,空數(shù)組無法執(zhí)行回調(diào)函數(shù)
9、數(shù)組去重
- ES6 Set去重: 無法去掉“{}”空對象
var set = new Set([1, 2, 3, 3, 4]); //先把數(shù)組轉(zhuǎn)化為set集合
Array.from(set) //輸出[1,2,3,4] 通過Array.from這個方法把集合在轉(zhuǎn)化為數(shù)組
[...new Set(arr)] //簡化寫法
- 利用for嵌套for涩搓,然后splice去重(NaN和{}沒有去重)
function unique(arr){
for(var i=0; i<arr.length; i++){
for(var j=i+1; j<arr.length; j++){
if(arr[i]===arr[j]){ //第一個等同于第二個污秆,splice方法刪除第二個
arr.splice(j,1);
j--;
}
}
}
return arr;
}
var arr = [false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[false, undefined, null, NaN, NaN, "NaN", 0, "a", {}, {}] NaN和{}沒有去重
- 利用indexOf去重: 新建一個空的結(jié)果數(shù)組,for 循環(huán)原數(shù)組昧甘,判斷結(jié)果數(shù)組是否存在當前元素良拼,如果有相同的值則跳過,不相同則push進數(shù)組(NaN和{}沒有去重)
function unique(arr) {
if (!Array.isArray(arr)) {
console.log('type error!')
return
}
var array = [];
for (var i = 0; i < arr.length; i++) {
if (array .indexOf(arr[i]) === -1) {
array .push(arr[i])
}
}
return array;
}
var arr = [false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[false, undefined, null, NaN, NaN, "NaN", 0, "a", {}, {}] NaN和{}沒有去重
- 利用sort(): 根據(jù)排序后的結(jié)果進行遍歷及相鄰元素比對(NaN和{}沒有去重)
function unique(arr) {
if (!Array.isArray(arr)) {
console.log('type error!')
return;
}
arr = arr.sort()
var arrry= [arr[0]];
for (var i = 1; i < arr.length; i++) {
if (arr[i] !== arr[i-1]) {
arrry.push(arr[i]);
}
}
return arrry;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//(14) [0, 1, 15, NaN, NaN, "NaN", {}, {}, "a", false, null, "true", true, undefined]
- 利用filter({}沒有去重)
function unique(arr) {
return arr.filter(function(item, index, arr) {
//當前元素疾层,在原始數(shù)組中的第一個索引==當前索引值将饺,否則返回當前元素
return arr.indexOf(item, 0) === index;
});
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "true", true, 15, false, undefined, null, "NaN", 0, "a", {}, {}]
- 利用hasOwnProperty (所有的都可以去重)
function removeDuplicates(arr){
var i, len=arr.length;
var array=[], obj={};
for(i=0; i<len; i++){
if(!obj.hasOwnProperty(arr[i])){
array.push(arr[i]);
obj[arr[i]] = true;
}
}
return array;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
// [1, "true", 15, false, undefined, null, NaN, 0, "a", {}]
- 利用includes:檢測數(shù)組是否有某個值({}沒有去重)
//和indexOf 去重方法類似,只是if()里改為!array.includes(arr[i])
10痛黎、數(shù)組隨機排序
- 法一予弧、
- 遍歷數(shù)組,每次循環(huán)都隨機一個在數(shù)組長度范圍內(nèi)的數(shù)湖饱,并交換本次循環(huán)的位置和隨機數(shù)位置上的元素
- 法二掖蛤、
- 申明一個新的空數(shù)組,利用while循環(huán),如果數(shù)組長度大于0井厌,就繼續(xù)循環(huán)蚓庭;
- 每次循環(huán)都隨機一個在數(shù)組長度范圍內(nèi)的數(shù)致讥,將隨機數(shù)位置上的元素push到新數(shù)組里,
- 并利用splice(對splice不太理解的同學可以看這里)截取出隨機數(shù)位置上的元素器赞,同時也修改了原始數(shù)組的長度垢袱;
- 法三、利用傳入sort排序中的比較函數(shù)
- 如果 compareFunction(a, b)的返回值 小于 0 港柜,那么 a 會被排列到 b 之前请契;
- 如果 compareFunction(a, b)的返回值 等于 0 ,那么a 和 b 的相對位置不變夏醉;
- 如果 compareFunction(a, b)的返回值 大于 0 爽锥,那么b 會被排列到 a 之前;
function randomSort3(arr){
arr.sort(function(a,b){
return Math.random() - 0.5;
});
return arr;
}
11畔柔、JavaScript數(shù)組迭代(遍歷)方法
forEach: 對數(shù)組中每一項運行給定函數(shù)氯夷。該函數(shù)沒有返回值
var arr = [1, 2, 3];
var obj = {name: 'zhang'};
arr.forEach(function (element, index, array) {
console.log(element, index, array, this)
}, obj)
// output
1 0 [1, 2, 3] {name: "zhang"}
2 1 [1, 2, 3] {name: "zhang"}
3 2 [1, 2, 3] {name: "zhang"}
以下方法有返回值(有返回值的方法,callback需要有return值)
map: 對數(shù)組中每一項運行給定函數(shù)靶擦。返回每次函數(shù)調(diào)用的結(jié)果組成的函數(shù)
var data = [1, 2, 3];
var arrayOfSquares = data.map(function (element) {
return element * element;
});
console.log(arrayOfSquares); //[1, 4, 9]
filter: 對數(shù)組中的每一項運行給定函數(shù)腮考。返回該函數(shù)會返回 true 的項組成的數(shù)組
var arr = [0, 1, 2, 3];
var newArr = arr.filter(function (element, index, array) {
return e;
})
var newArr2 = arr.filter(function (element, index, array) {
return e>=2;
})
console.log(newArr); // [1, 2, 3]
console.log(newArr2); // [2, 3]
some: 對數(shù)組中每一項運行給定函數(shù)。如果函數(shù)對 任一項返回 true奢啥,則返回 true
function isBigEnough(element, index, array) {
return element >= 4;
}
var passed = [1, 2, 3].some(isBigEnough);
var passed2 = [1, 2, 3, 4].some(isBigEnough);
console.log(passed); // false
console.log(passed2); // true
every: 對數(shù)組中的每一項運行給定函數(shù)秸仙。如果函數(shù)對每一項都返回 true,則返回 true
function isBigEnough(element, index, array) {
return element >= 3;
}
var passed = [2, 3, 4].every(isBigEnough);
var passed2 = [3, 4, 5].every(isBigEnough);
console.log(passed); // false
console.log(passed2); // true
find / findIndex: 用于找出第一個符合條件的數(shù)組成員返回undefined/-1
var value = [1, 5, 10, 15].find(function(element, index, array) {
return element > 9;
});
var value2 = [1, 5, 10, 15].find(function(element, index, array) {
return element > 20;
});
console.log(value); // 10
console.log(value2); // undefined
以上方法中的callback函數(shù)會被依次傳入三個參數(shù):
數(shù)組當前項的值
數(shù)組當前項的索引
數(shù)組對象本身
還可以傳入第二個可選參數(shù)桩盲,callback函數(shù)里的this將指向這個參數(shù)寂纪。默認this指向全局對象(在瀏覽器是為window),嚴格模式下是undefined
reduce / reduceRight: 讓數(shù)組中的前項和后項某種計算赌结,并累計最終值/從最后一個值開始計算的
var sum = [1, 2, 3].reduce(function(a, b) {
return a + b;
});
console.log(sum); // 6
其中callback可以依次接受四個參數(shù):
accumulator上一次調(diào)用回調(diào)返回的值捞蛋,或者是提供的初始值(initialValue)
currentValue數(shù)組中正在處理的元素
currentIndex數(shù)組中正在處理的元素索引,如果提供了initialValue 柬姚,從0開始拟杉;否則從1開始。
array數(shù)組對象本身
reduce / reduceRight 方法中量承,第二個參數(shù)(initialValue)是可選的搬设;其值用于第一次調(diào)用callback的第一個參數(shù)。
var sum = [0,1,2,3,4].reduce(function(accumulator, currentValue, currentIndex, array){
console.log(accumulator, currentValue, currentIndex, array)
return accumulator + currentValue;
}, 10);
console.log(sum);
// output
10 0 0 [0, 1, 2, 3, 4]
10 1 1 [0, 1, 2, 3, 4]
11 2 2 [0, 1, 2, 3, 4]
13 3 3 [0, 1, 2, 3, 4]
16 4 4 [0, 1, 2, 3, 4]
20