1、 new操作符都做了哪些事,手寫new操作符
function myNew(func,...args){
//1.創(chuàng)建一個新的空對象
const newObj = {}
//2.將新對象的原型指向構(gòu)造函數(shù)的原型
newObj._proto_ = func.prototype
//3.將構(gòu)造函數(shù)的this指向新對象
let result = apply(newObj,args)
//4.處理構(gòu)造函數(shù)的返回值,根據(jù)返回值進行判斷,判斷是基本類型還是引用類型
return result instanceof Object ? result : newObj
}
2、閉包的理解,手寫一個閉包函數(shù)使用場景
- 閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)
- 閉包是為了設(shè)計私有方法和變量,實現(xiàn)js封裝
- 函數(shù)嵌套函數(shù),內(nèi)部函數(shù)可以訪問外部函數(shù)的變量
//1.解決for循環(huán)問題
for(var i = 0;i<5,i++){
(function(j){
setTimeOut(function(){
console.log(j) // 0 1 2 3 4
},500)
})(i)
}
3、手寫防抖和節(jié)流函數(shù)
- 防抖:應(yīng)用于搜索框輸入、窗口大小調(diào)整、表單提交事件
function debonce(func,delay){
let timer = null
return function(...args){
if(timer) clearTimeout(timer);
timer = setTimeout(()=>{
func.apply(this,args) //延遲執(zhí)行
},delay)
}
}
const searchInput = document.getElementById("myInput")
const fetchData = () => console.log("發(fā)送請求")
searchInput.addEventListener("input",debonce(fetchData,500))
- 節(jié)流:應(yīng)用于滾動加載、鼠標移動事件、高頻觸發(fā)事件
function throttle(func,delay){
let timer = null
return function(...args){
if(!timer){
timer = setTimeout(()=>{
func.apply(this,args)
timer = null
},delay)
}
}
}
window.addEventListener("scroll",throttle(()=>{
console.log("滾動加載數(shù)據(jù)")
},1000))
4、js實現(xiàn)快速排序算法
1.快速排序是一種高效的排序算法,采用分治策略
function quickSort(arr) {
// 如果數(shù)組長度小于等于1,直接返回(遞歸的終止條件)
if (arr.length <= 1) {
return arr;
}
// 選擇基準值(pivot),這里選擇中間元素
const pivotIndex = Math.floor(arr.length / 2);
const pivot = arr[pivotIndex];
// 定義左右兩個數(shù)組
const left = [];
const right = [];
// 遍歷數(shù)組,將元素分配到左右兩個數(shù)組
for (let i = 0; i < arr.length; i++) {
if (i === pivotIndex) continue; // 跳過基準元素
if (arr[i] < pivot) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
// 遞歸調(diào)用并合并結(jié)果
return [...quickSort(left), pivot, ...quickSort(right)];
}
// 使用示例
const unsortedArray = [3, 6, 8, 10, 1, 2, 1];
const sortedArray = quickSort(unsortedArray);
console.log(sortedArray); // 輸出: [1, 1, 2, 3, 6, 8, 10]
2.為了更高效地實現(xiàn)快速排序,通常使用Lomuto分區(qū)方案,即在數(shù)組中選擇最后一個元素作為基準值,并通過一次遍歷來重新排列數(shù)組
function quickSort(arr, left = 0, right = arr.length - 1){
if(left < right){
const pivotIndex = partition(arr, left, right);
quickSort(arr, left, pivotIndex - 1);
quickSort(arr, pivotIndex + 1, right);
}
return arr
}
function partition(arr, left, right){
const pivot = arr[right]; //選擇最右邊元素作為基準
let i = left;
for(let j = left; j < right; j++){
if(arr[j] < pivot){
[arr[i], arr[j]] = [arr[j], arr[i]]; //交換元素
i++;
}
}
[arr[i], arr[right]] = [arr[right], arr[i]]; //將基準放到正確位置
return i;
}
//使用示例
const array = [3,6,8,10,1,2,1]
quickSort(array);
console.log(array);
5、實現(xiàn)淺拷貝和深拷貝
- 淺拷貝方法
//1.Object.assign()
const obj = { a: 1, b: { c: 2 } };
const shallowCopy = Object.assign({}, obj);
shallowCopy.b.c = 3; // 修改嵌套對象
console.log(obj.b.c); // 3(原對象也被修改)
//2. 擴展運算符 ...
const obj = { a: 1, b: { c: 2 } };
const shallowCopy = { ...obj };
shallowCopy.b.c = 3;
console.log(obj.b.c); // 3(原對象也被修改)
//3.數(shù)組的slice()方法
const arr = [1, 2, { a: 3 }];
const shallowCopy = arr.slice();
shallowCopy[2].a = 4;
console.log(arr[2].a); // 4(原數(shù)組也被修改)
//4.Array.from()
const arr = [1, 2, { a: 3 }];
const shallowCopy = Array.from(arr);
shallowCopy[2].a = 4;
console.log(arr[2].a); // 4(原數(shù)組也被修改)
//5. 使用賦值運算符(=)進行拷貝
const a = [1, 2, 3];
const b = a; // 淺拷貝
b[0] = 4;
console.log(a); // [4, 2, 3]
console.log(b); // [4, 2, 3]
- 深拷貝方法
//1. JSON.parase(JSON.stringify(obj))
const obj = { a: 1, b: { c: 2 } };
const deepCopy = JSON.parse(JSON.stringify(obj));
deepCopy.b.c = 3;
console.log(obj.b.c); // 2(原對象不受影響)
缺點:
不能復(fù)制 undefined、function、Symbol。
不能處理循環(huán)引用(如 obj.self = obj)。
會丟失 Date 對象(轉(zhuǎn)為字符串)。
//2.遞歸手動實現(xiàn)
function deepClone(obj, hash = new WeakMap()) {
if (obj === null || typeof obj !== "object") return obj;
if (hash.has(obj)) return hash.get(obj); // 解決循環(huán)引用
const clone = Array.isArray(obj) ? [] : {};
hash.set(obj, clone);
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
clone[key] = deepClone(obj[key], hash);
}
}
return clone;
}
// 測試
const obj = { a: 1, b: { c: 2 }, d: [3, 4] };
const deepCopy = deepClone(obj);
deepCopy.b.c = 99;
deepCopy.d.push(5);
console.log(obj); // { a: 1, b: { c: 2 }, d: [3, 4] }(原對象不變)