1.為什么要手寫代碼?
我們在日常開發(fā)過程中,往往都是取出來直接用,從來不思考代碼的底層實現(xiàn)邏輯,但當(dāng)我開始研究一些底層的東西的時候,才開始理解了JavaScript每個方法和函數(shù)的底層實現(xiàn)思路,我認(rèn)為這可以很好的提高我們的代碼水平和邏輯思維。
2.手寫實現(xiàn)數(shù)組方法
2.1 push
push 從后面添加元素 返回push完以后數(shù)組的長度
2.1.1 基本使用
let arr = [1, 2];
console.log(arr.push(1, 2, 3)); // 5
console.log(arr); // [1,2,1,2,3]
2.1.2 手寫實現(xiàn)
數(shù)組方法在數(shù)組的原型對象上
Array.prototype.myPush = function () {
for (let i = 0; i < arguments.length; i++) {
// this就是調(diào)用該方法的數(shù)組arr,
// 數(shù)組當(dāng)前最后一項的索引為 this.length - 1,再往后面加索引就為this.length
this(this.length) = arguments[i]
}
return this.length
};
調(diào)用測試
正常打印
console.log(arr.myPush(1, 2, 3)); // 5
console.log(arr); // [1,2,1,2,3]
2.2 pop
刪除數(shù)組的最后一位元素,返回被刪除的那個元素。此方法更改數(shù)組的長度。
2.2.1 基本使用
let arr = [1, 2, 3];
console.log(arr.pop()); // 3
console.log(arr); // [1,2]
2.2.2 手寫實現(xiàn)
Array.prototype.myPop = function () {
let result = this[this.length - 1];
this.length = this.length - 1;
return result;
};
console.log(arr.myPop()); // 3
console.log(arr); // [1,2]
2.3 shift
從數(shù)組中刪除第一個元素,并返回該元素的值。此方法更改數(shù)組的長度。
2.3.1 基本使用
let arr = [1, 2, 3];
console.log(arr.shift()); // 1
console.log(arr); // [2,3]
2.3.2 手寫實現(xiàn)
Array.prototype.myShift = function () {
let result = this[0];
for (let i = 0; i < this.length; i++) {
// 后面的元素依次賦給前一項
// 因為數(shù)組的第一個元素已經(jīng)刪除
this[i] = this[i + 1];
}
// 改變數(shù)組長度
this.length--;
// 返回被刪除的元素
return result;
};
console.log(arr.myShift()); // 1
console.log(arr); // [2,3]
2.4 unshift
將一個或多個元素添加到數(shù)組的開頭,并返回該數(shù)組的新長度。
2.4.1 基本使用
let arr = [1, 2, 3];
console.log(arr.unshift(4, 5)); // 5
console.log(arr); // [4,4,1,2,3]
2.4.2 手寫實現(xiàn)
Array.prototype.myUnshift = function () {
// 最終數(shù)組的長度sum = 原數(shù)組長度 + unshift傳入的參數(shù)的個數(shù)
let sum = this.length + arguments.length;
for (let i = sum; i > 0; i--) {
// 如果還沒往后遍歷到傳入的參數(shù)的時候
// 原數(shù)組的值依次往向后賦值
if (i > arguments.length) {
this[i - 1] = this[i - 1 - arguments.length];
} else {
this[i - 1] = arguments[i - 1];
}
}
return sum;
};
console.log(arr.myUnshift(4, 5)); // 5
console.log(arr); // [4,5,1,2,3]
2.5 splice
2.5.1 基本使用
splice() 方法用于添加或刪除數(shù)組中的元素。會改變原始數(shù)組。
語法:
array.splice(index,howmany,item1,.....,itemX)
第一個參數(shù)index:必需。規(guī)定從何處添加/刪除元素。
第二個參數(shù)howmany:可選。規(guī)定應(yīng)該刪除多少元素。必須是數(shù)字,但可以是 “0”。
后續(xù)參數(shù):可選。要添加到數(shù)組的新元素
使用示例
不傳入?yún)?shù),不進行操作,返回[],原數(shù)組不發(fā)生改變
let arr = [1, 2, 3, 4];
console.log(arr.splice()); // []
console.log(arr); // [1, 2, 3, 4]
傳入一個參數(shù)index 刪除索引1后面的元素,原數(shù)組發(fā)生改變
let arr = [1, 2, 3, 4];
console.log(arr.splice(1)); // [2,3,4]
console.log(arr); // [1]
傳入兩個參數(shù)index howmany,從索引0開始刪除 2 個元素
let arr1 = [1, 2, 3, 4];
console.log(arr1.splice(0, 2)); // [1,2]
console.log(arr1); // [3,4]
傳入三個參數(shù) index howmany 其他參數(shù),從索引0開始刪除2個元素,并用后面的參數(shù)替換。
let arr2 = [1, 2, 3, 4];
console.log(arr2.splice(0, 2, 5, 6)); // [1,2]
console.log(arr2); // [5,6,3,4]
2.5.2 手寫實現(xiàn)
Array.prototype.mySplice = function (index, num, ...args) {
let newArr = [];
let returnArr = [];
// 如果沒有傳入?yún)?shù),直接返回空數(shù)組
if (index == undefined || num == 0) return [];
if (index < 0) index = index + this.length;
// 如果沒有傳入截取數(shù)組的長度,自己手動計算
if (!num) {
// 這里是將num轉(zhuǎn)換為索引值,方便后續(xù)的遍歷
num = this.length - index + 1;
} else if (num > 0) {
num = num + index;
}
// 遍歷index之前的數(shù)組,賦給newArr
for (let i = 0; i < index; i++) {
newArr.push(this[i]);
}
// 遍歷我們要刪除的數(shù)組范圍
for (; index < num; index++) {
returnArr.push(this[index]);
}
// 如果傳入其他參數(shù),就傳入的參數(shù)添加進去
if (args.length > 0) {
newArr.push(...args);
}
// 遍歷num后面的數(shù)組,賦給newArr
for (let i = num; i < this.length; i++) {
newArr.push(this[i]);
}
// newArr 是我們想要的原數(shù)組的值
for (let i = 0; i < newArr.length; i++) {
this[i] = newArr[i];
}
// 截取長度
this.length = newArr.length;
return returnArr;
};
console.log(arr.mySplice());
console.log(arr.mySplice(1)); // [2,3,4]
console.log(arr); // [1]
let arr1 = [1, 2, 3, 4];
console.log(arr1.mySplice(0, 0)); // [1,2]
console.log(arr1); // [3,4]
let arr2 = [1, 2, 3, 4];
console.log(arr2.mySplice(0, 2, 5, 6)); // [1,2]
console.log(arr2); // [5,6,3,4]
2.6 fill
2.6.1 基本使用
fill() 方法用于將一個固定值替換數(shù)組的元素。
語法:
array.fill(value, start, end)
第一個參數(shù)value:必需。填充的值。
第二個參數(shù)start:可選。開始填充位置。
第三個參數(shù)end:可選。停止填充位置 (默認(rèn)為 array.length)
使用示例
let arr = [1, 2, 3, 4];
console.log(arr.fill(4));
console.log(arr); // [4, 4, 4, 4]
arr.fill(5, 0, 2);
console.log(arr); // [5, 5, 4, 4]
console.dir(Array.prototype);
2.6.2 手寫實現(xiàn)
Array.prototype.myFill = function (value, start = 0, end = this.length) {
if (start && start < 0) start = this.length + start;
if (end && end < 0) end = this.length + end;
for (; start < end; start++) {
this[start] = value;
}
return this;
};
console.log(arr.fill(4));
console.log(arr); // [4, 4, 4, 4]
arr.fill(5, 0, 2);
console.log(arr); // [5, 5, 4, 4]
2.7 reverse
2.7.1 基本使用
reverse() 方法用于反轉(zhuǎn)數(shù)組中元素的順序。
let arr = [1, 2, 3, 4, 5];
arr.reverse();
console.log(arr); // [5, 4, 3, 2, 1]
2.7.2 手寫實現(xiàn)
Array.prototype.myReverse = function () {
let len = this.length - 1;
for (let i = 0; i < Math.floor(this.length / 2); i++) {
// 交換這兩個元素位置
let temp = arr[i];
arr[i] = arr[len];
arr[len--] = temp;
}
return this;
};
arr.myReverse();
console.log(arr); // [5, 4, 3, 2, 1]
2.8 sort
2.8.1 基本使用
sort() 方法用于對數(shù)組的元素進行排序。
排序順序可以是字母或數(shù)字,并按升序或降序。
默認(rèn)排序順序為按字母升序。
這種方法會改變原始數(shù)組!
這里只是實現(xiàn)了對數(shù)字的排序,大家有具體的思路可以評論區(qū)討論
使用實例
let arr = [1, 3, 2, 4];
arr.sort((a, b) => b - a);
console.log(arr); // [4,3,2,1]
2.8.2 手寫實現(xiàn)
利用冒泡排序進行重構(gòu)。
Array.prototype.mySort = function (callback) {
// 使用了冒泡排序
for (let i = 0; i < this.length - 1; i++) {
for (let j = 0; j < this.length - 1 - i; j++) {
if (callback(this[j], this[j + 1]) > 0) {
let temp = this[j];
this[j] = this[j + 1];
this[j + 1] = temp;
}
}
return this;
}
};
arr.mySort((a, b) => a - b);
console.log(arr);
2.9 copyWithin
2.9.1 基本使用
copyWithin() 方法用于從數(shù)組的指定位置拷貝元素到數(shù)組的另一個指定位置中。
語法:
array.copyWithin(target, start, end)
第一個參數(shù)target:必需。復(fù)制到指定目標(biāo)索引位置。
第二個參數(shù)start:可選。元素復(fù)制的起始位置。默認(rèn)起始位置為0
第三個參數(shù)end:可選。停止復(fù)制的索引位置 (默認(rèn)為 array.length)。如果為負(fù)值,表示倒數(shù)。文章來源:http://www.zghlxwxcb.cn/news/detail-503028.html
使用示例:
復(fù)制數(shù)組的前面兩個元素到第三和第四個位置上:文章來源地址http://www.zghlxwxcb.cn/news/detail-503028.html
let arr = [1, 2, 3, 4, 5];
arr.copyWithin(2, 0, 2);
console.log(arr); // [1, 2, 1, 2, 5]
2.9.2 手寫實現(xiàn)
Array.prototype.myCopyWithin = function (target, start = 0, end = this.length) {
let newArr = [];
if (target < 0) target = this.length + target;
if (start < 0) start = this.length + start;
if (end < 0) end = this.length + end;
for (let i = start; i < end; i++) {
newArr.push(this[i]);
}
let arrLength = newArr.length;
let k = 0;
// 同時判斷賦值的區(qū)間和待拷貝數(shù)組的長度的大小
let len = arrLength < this.length - target ? target + arrLength : this.length;
for (; target < len; target++) {
console.log(newArr[k]);
this[target] = newArr[k++];
}
return this;
};
歡迎大家在討論學(xué)習(xí),感謝大家支持 |
到了這里,關(guān)于JavaScript 手寫代碼 第五期(重寫數(shù)組方法一)-可以改變原數(shù)組的方法的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!