js底層面試題+代碼(機試)

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] }(原對象不變)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容