js中陣列常用方法的簡單重構(部分),幫助你加快理解陣列中常用方法
阿新 • • 發佈:2020-03-29
## `push`
將指定數字插入到陣列的末尾,返回值為`新陣列的長度`
```javascript
//原方法示例:
var ary = [1, 2, 3, 4, 5];
ary.length = 5;
ary.push(1) ;
ary = [1,2,3,4,5,1];
ary.length = 6;
//方法重構:
Array.prototype.myPush = function () {
for (i = 0; i < arguments.length; i++) {
this[this.length] = arguments[i];
}
return this.length
}
```
## `pop`
將陣列最後的元素刪除,返回值為`刪除掉的元素`
```javascript
//原方法示例:
var ary = [1, 2, 3, 4, 5];
var num = ary.pop();
console.log(num); == 5
//方法重構:
Array.prototype.myPop = function () {
var num = this[this.length - 1];
this.length--
return num
}
```
## `unshift`
將指定的數字插入到元素的前面,返回值為`新陣列的長度`
```javascript
//原方法示例:
var ary = [1, 2, 3, 4, 5];
ary.length = 5;
ary.unshift(1) ;
ary = [1,1,2,3,4,5];
ary.length = 6;
//方法重構:
Array.prototype.myUnshift = function () {
var len = this.length; //用一個變數儲存原來的陣列的長度
this.length += arguments.length; //傳入進來幾個引數,陣列的長度就增加傳入進來的引數的長度
for (var i = 0; i < arguments.length; i++) {
/* 整體需要進行幾輪的迴圈,迴圈的輪數應該與傳入進來的實參長度相等,因為第一輪的時候只是將陣列整體往後面移了一個位置,想要前面能夠有足夠實參插入的長度,那麼迴圈的輪數就是由實參的長度所確定的*/
for (var j = len; j > 0; j--) {
/* 因為往前面插入,所以將陣列的中原來的值往後移動,並且從最後一位開始移動才能使陣列中的元素不被覆蓋 */
this[j] = this[j - 1];
/* 讓後面為空的元素等於前面的值,將陣列的值依次往後移動 */
}
len++; /* 內部迴圈完畢後,此時的原陣列的最後一位已經往後移動了一位,如果還需要將陣列往後繼續進行移動的話,那麼就應該從原陣列的最後一位繼續往後移動,所以此時的len就應該加一。如果不進行加一操作的話,會把後面的元素覆蓋掉,並且整個陣列將不會再往後移動,後面都是空元素 */
}
return this.length
}
```
## `shift`
將陣列的第一個元素刪除並返回,返回值為`被刪除的元素`
```javascript
//原方法示例:
var ary = [1, 2, 3, 4, 5];
var num = ary.shift();
console.log(num); === 1
//方法重構:
Array.prototype.myShift = function () {
var num = this[0];
var len = this.length;
for (var i = 0; i < len; i++) {
this[i] = this[i + 1];
}
this.length--;
return num
}
```
## `concat`
將陣列進行拼接,返回值是`拼接後的陣列`(傳入的引數中有陣列,並且其中存在空元素,`空元素也會進行拼接`)
```javascript
//原方法示例:
var ary = [1, 2, 3, 4, 5];
var ary1 = ary.concat([1, 2, 3, , 4], {a:1})
console.log(ary1) === [1, 2, 3, 4, 5, 1, 2, 3, , 4, {a:1}]
//方法重構:
Array.prototype.myConcat = function () {
var ary = this;
for (var i = 0; i < arguments.length; i++) {
if (arguments[i].constructor === Array) {
for (var j = 0; j < arguments[i].length; j++) {
ary[ary.length] = arguments[i][j];
}
} else {
ary[ary.length] = arguments[i];
}
}
return ary
}
```
## `join`
將陣列用傳入的引數進行拼接,返回值為`拼接後的字串`(不傳入引數,預設為`""`)
```javascript
//原方法示例:
var ary = [1, 2, 3, 4, 5];
var str = ary.join();
console.log(str) === "1,2,3,4,5"
//方法重構:
Array.prototype.myJoin = function () {
var str = "";
if (arguments[0] === "" || arguments[0] === undefined) {
for (i = 0; i < this.length - 1; i++) {
str += this[i] + ",";
}
} else {
for (i = 0; i < this.length - 1; i++) {
str += this[i] + arguments[0];
}
}
str += this[this.length - 1];
return str
}
```
## `some`
第一個傳入的引數為一個函式,該函式有三個引數,分別為`item、index、ary`,將該函式執行,返回執行結果,如果`結果中有一個true結束執行`,`沒有true將一直查詢`下去。返回值為`布林值`
```javascript
//原方法示例:
var ary = [1, 2, 3, 4, 5];
var bool = ary.some(function(item,index,ary){
return item > 4;
})// true
//方法重構:
Array.prototype.mySome = function () {
for (var i = 0; i < this.length; i++) {
var bool = arguments[0](this[i], i, this);
if (bool) return true;
}
return false;
}
```
## `every`
第一個傳入的引數為一個函式,該函式有三個引數,分別為`item、index、ary`,將該函式執行,返回執行結果,如果`結果中有一個false結束執行`,`沒有false將一直查詢`下去。返回值為`布林值`
```javascript
//原方法示例
var ary = [1, 2, 3, 4, 5];
var bool = ary.every(function(item,index,ary){
return item > 1;
})// false
//方法重構
Array.prototype.myEvery = function () {
for (var i = 0; i < this.length; i++) {
var bool = arguments[0](this[i], i, this);
if (!bool) return false;
}
return true;
}
```
## `slice`
可傳入兩個引數,第一個引數代表這`起始下標位置`,第二個引數選填,代表到這個`數字下標前結束`.
不傳引數,`預設擷取到末尾,引數也可為負數`.
返回值`擷取的陣列成的陣列,原陣列不變`
```javascript
//原方法示例:
var ary = [1, 2, 3, 4, 5];
ary.slice() ===> [1, 2, 3, 4, 5];
ary.slice(1,3) ===> [2, 3]
ary.slice(-3,-1) ===> [3, 4]
//方法重構:
Array.prototype.mySlice = function () {
/*
分為兩種情況:
1、當arguments[1]為0時,或者為undefined時,此時有以下情況:
1、如果此時的arguments[1]是undefined時有以下情況:
1、當arguments[0]大於等於0時,從arguments位下標開始往後擷取
2、當arguments[0]為undefined時,複製一份原陣列
3、其他情況都返回空陣列
2、當arguments[1]為true時,有以下情況:
1、正常情況下,當arguments[0]小於等於arguments[1]時,有以下情況
1、兩個引數都是大於0的情況下(arguments[0]可等於0),從arguments[0]位下標開始複製到arguments[1]位下標前一位結束
2、兩個引數都小於0時,此時的開始位置(arguments[0])和結束位置(arguments[1])應該都加上陣列的長度
2、除去上面的情況,都為非正常情況,所以都返回空陣列
*/
var ary = [];
if (arguments[1] > this.length) arguments[1] = this.length;
//判斷傳入的第二個引數是否超出陣列的長度,如果超出,則讓它預設為陣列的長度
if (!arguments[1]) {
//當argumens為0或者不傳時
if (typeof arguments[1] === 'undefined') {
//判斷當argumens[1]是否為undefined,如果是,進入此語句
if (arguments[0] >= 0) { //當argumens[0]
for (var i = arguments[0]; i < this.length; i++) {
ary[ary.length] = this[i];
}
return ary
} else if (typeof arguments[0] === 'undefined') {
for (var j = 0; j < this.length; j++) {
ary[ary.length] = this[i];
}
return ary
}
} else return ary //除去上述情況都為非正常情況,返回空陣列
} else {
//否則當argument[1]>0時進入此語句
if (arguments[0] <= arguments[1]) {
//正常情況下開始位置總會小於等於結束位置
if (arguments[0] >= 0 && arguments[1] > 0) {
//第一種情況:兩個都大於0時(arguments[0]可以等於0)
for (var k = arguments[0]; k < arguments[1]; k++) {
//直接複製
ary[ary.length] = this[k];
}
return ary
} else if (arguments[0] < 0 && arguments[1] < 0) {
//第二種情況:兩個都小於0時
for (var n = arguments[0] + this.length; n < arguments[1] + this.length; n++) {
//首先需要將兩個負的引數都加上陣列的長度變為正
ary[ary.length] = this[n];
}
return ary
} else return ary //除去上述情況都為非正常情況,返回空陣列
} else return ary //除去上述情況都為非正常情況,返回空陣列
}
}
```
## `forEach`
將陣列中的每一項進行遍歷,`不遍歷空元素`,`無返回值`
```javascript
Array.prototype.myForEach = function () {
var len = this.length-1;
for (var item in this) {
if (len === 0) break;
arguments[0](this[item],item,this);
len--;
}
}
```
## `map`
將陣列中的每一項進行遍歷,返回一個`與原陣列長度相同的陣列`
```javascript
// 原方法示例:
var ary = [1, 2, 3, 4, 5];
ary.map(function(item,index,ary){
return item * 2
}) === [2,4,6,8,10]
// 方法重構:
Array.prototype.myMap = function () {
var ary = [];
ary.length = this.length;
var len = ary.length-1;
for (var item in this) {
if (len === 0) break;
ary[item] = arguments[0](this[item],item.this);
len--;
}
return ary
}
```
## `filter`
第一個傳入的引數為一個函式,函式中可傳入三個引數,分別為`item、index、ary`,返回值是`一個由所有滿足條件的元素所組成的陣列`
```javascript
//原方法示例:
var ary = [1, 2, 3, 4, 5];
ary.filter(function(item,index,ary){
return item > 2
}) === [3,4,5]
//方法重構:
Array.prototype.myFilter = function () {
var ary = [];
for (var i = 0; i < this.length; i++) {
var bool = arguments[0](this[i], i, this);
if (bool) {
ary[ary.length] = this[i];
}
}
return ary
}
```
## `reduce`
第一個傳入的引數為一個函式,函式中可傳入四個引數,分別為`value、item、index、ary`,返回`計算後第一個引數的值`,返回值為`一個值`
如果有傳入第二個引數,那麼`第一個引數的第一個引數的預設值就為它`,並且`第一個引數的第二個引數從陣列的第0位起始`;
否則,未傳入,那麼`第一個引數的第一個引數就時陣列的第0位`,並且`第一個引數的第二個引數從陣列的第1位起始`
```javascript
//原方法示例:
var ary = [1, 2, 3, 4, 5];
var num = ary.reduce(function(value,item,index,ary){
return value + item;
})
console.log(num) === 15
//方法重構:
Array.prototype.myReduce = function () {
var initValue;
var i = 0;
if (arguments[1] || arguments[1] === 0) {
initValue = arguments[1];
} else {
initValue = this[0];
i++;
}
while (i < this.length) {
initValue = arguments[0](initValue, this[i], i, this);
i++;
}
return initValue;
}
```
## `reduceRight`
第一個傳入的引數為一個函式,函式中可傳入四個引數,分別為`value、item、index、ary`,返回`計算後第一個引數的值`,返回值為`一個值`
如果有傳入第二個引數,那麼`第一個引數的第一個引數的預設值就為它`,並且`第一個引數的第二個引數從陣列的第length-1位起始`;
否則,未傳入,那麼`第一個引數的第一個引數就時陣列的第length-1位`,並且`第一個引數的第二個引數從陣列的第length-2位起始`
```javascript
//原方法示例:
var ary = [1, 2, 3, 4, 5];
var num = ary.reduceRight(function(value,item,index,ary){
return value + item;
})
console.log(num) === 15
//方法重構:
Array.prototype.myReduceRight = function () {
var initValue;
var i = this.length - 1;
if (arguments[1] || arguments[1] === 0) {
initValue = arguments[1];
} else {
initValue = this[this.length - 1];
i--;
}
while (i >= 0) {
initValue = arguments[0](initValue, this[i], i, this);
i--
}
return initVal