1. 程式人生 > >js中陣列常用方法的簡單重構(部分),幫助你加快理解陣列中常用方法

js中陣列常用方法的簡單重構(部分),幫助你加快理解陣列中常用方法

## `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