算法题

100 阅读11分钟

1、深拷贝

function deepClone(obj) {
  if (obj === null || typeof obj !== 'object') {
    return obj; // 如果是基本类型或null,则直接返回
  }

  if (Array.isArray(obj)) {
    const cloneArr = [];
    for (let i = 0; i < obj.length; i++) {
      cloneArr[i] = deepClone(obj[i]);
    }
    return cloneArr;
  }

  if (typeof obj === 'object') {
    const cloneObj = {};
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        cloneObj[key] = deepClone(obj[key]);
      }
    }
    return cloneObj;
  }
}

2、promiseAll异步实现

function promiseAll(promises) {
  return new Promise((resolve, reject) => {
    const results = [];
    let completed = 0;

    if (promises.length === 0) {
      resolve(results);
    } else {
      promises.forEach((promise, index) => {
        Promise.resolve(promise)
          .then((result) => {
            results[index] = result;
            completed++;
            if (completed === promises.length) {
              resolve(results);
            }
          })
          .catch(reject);
      });
    }
  });
}

3、给你一个字符串s和一个字符串列表wordDict作为字典,请你判断是否可以利用字典中出现的单词拼接出s,不要求字典中出现的单词全部都使用,并且单词可以重复使用

例如: s="applepenapple" wordDict=["apple","pen"] 输出true

function wordBreak(s, wordDict) {
  const n = s.length;
  const dp = new Array(n + 1).fill(false);
  dp[0] = true;

  for (let i = 1; i <= n; i++) {
    for (let j = 0; j < i; j++) {
      if (dp[j] && wordDict.includes(s.substring(j, i))) {
        dp[i] = true;
        break;
      }
    }
  }

  return dp[n];
}

const s = "applepenapple";
const wordDict = ["apple", "pen"];
const result = wordBreak(s, wordDict);
console.log(result); // Output: true
//这段代码使用动态规划来检查字符串 `s` 是否可以通过字典 `wordDict` 中的单词拼接而成。
//在示例中,返回 `true`,因为 "applepenapple" 可以拆分为 "apple", "pen", "apple"。

4、给你一个包含n个整数的数组nums,判断nums中是否存在三个元素a,b,c 使得a+b+c=0?请找出所有和为0且不重复的三元组,注意:答案中不包括重复的三元组

示例:输入:nums = [-1,0,1,2,-1,-4] 输出 [[-1,-1,2],[-1,0,2]]

function threeSum(nums) {
  nums.sort((a, b) => a - b);
  const result = [];

  for (let i = 0; i < nums.length - 2; i++) {
    if (i === 0 || (i > 0 && nums[i] !== nums[i - 1])) {
      let lo = i + 1;
      let hi = nums.length - 1;
      const sum = 0 - nums[i];

      while (lo < hi) {
        if (nums[lo] + nums[hi] === sum) {
          result.push([nums[i], nums[lo], nums[hi]);
          while (lo < hi && nums[lo] === nums[lo + 1]) lo++;
          while (lo < hi && nums[hi] === nums[hi - 1]) hi--;
          lo++;
          hi--;
        } else if (nums[lo] + nums[hi] < sum) {
          lo++;
        } else {
          hi--;
        }
      }
    }
  }

  return result;
}

const nums = [-1, 0, 1, 2, -1, -4];
const result = threeSum(nums);
console.log(result); // Output: [[-1, -1, 2], [-1, 0, 1]]
//这段代码会找出数组 `nums` 中所有和为 0 的不重复三元组,并返回结果。
//在示例中,返回 `[[-1, -1, 2], [-1, 0, 1]]`。

5、实现一个stringfy,实现以后支持换行和缩进

function customStringify(obj, indent = 2) {
  return JSON.stringify(obj, null, indent);
}

const obj = {
  name: "John",
  age: 30,
  address: {
    city: "New York",
    zip: "10001",
  },
};

const jsonString = customStringify(obj, 4);
console.log(jsonString);
//这个 `customStringify` 函数接受两个参数:要转换的对象和缩进级别(默认为2)。
//它使用 `JSON.stringify`,并通过传递缩进级别来支持换行和缩进。

6、求一个数所有质因子的最大和

function primeFactorsSum(n) {
  let sum = 0;
  for (let i = 2; i <= n; i++) {
    while (n % i === 0) {
      sum += i;
      n /= i;
    }
  }
  return sum;
}

const number = 30;
const result = primeFactorsSum(number);
console.log(result); // Output: 17 (2 + 3 + 5 + 7)
//这个函数遍历从2到给定数 `n` 的所有整数,找到所有质因子并求和。

7、实现一个带限制次数的请求方法 reuest(urls,limit);

function request(urls, limit) {
  const results = [];
  const inProgress = [];
  let currentIndex = 0;

  function fetchNext() {
    if (currentIndex === urls.length) {
      return Promise.resolve();
    }

    const url = urls[currentIndex];
    const requestPromise = fetch(url)
      .then((response) => response.json())
      .then((data) => {
        results[currentIndex] = data;
      })
      .finally(() => {
        const index = inProgress.indexOf(requestPromise);
        if (index !== -1) {
          inProgress.splice(index, 1);
        }
      });

    inProgress.push(requestPromise);
    currentIndex++;

    if (inProgress.length >= limit) {
      return Promise.race(inProgress).then(fetchNext);
    }

    return fetchNext();
  }

  return fetchNext().then(() => results);
}

const urls = [...]; // Your array of URLs to request
const limit = 3; // Limit the number of concurrent requests

request(urls, limit).then((results) => {
  console.log(results);
});
//这个函数使用 `fetch` 来并行请求一组 URL,但限制并发请求数量为 `limit`。

8、给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

class TreeNode {
  constructor(val) {
    this.val = val;
    this.left = null;
    this.right = null;
  }
}

function lowestCommonAncestor(root, p, q) {
  if (root === null) return null;

  if (root.val === p.val || root.val === q.val) return root;

  const left = lowestCommonAncestor(root.left, p, q);
  const right = lowestCommonAncestor(root.right, p, q);

  if (left && right) return root;
  return left || right;
}

// 示例用法
const root = new TreeNode(3);
root.left = new TreeNode(5);
root.right = new TreeNode(1);
root.left.left = new TreeNode(6);
root.left.right = new TreeNode(2);
root.right.left = new TreeNode(0);
root.right.right = new TreeNode(8);
root.left.right.left = new TreeNode(7);
root.left.right.right = new TreeNode(4);

const p = root.left;
const q = root.left.right.right;

const result = lowestCommonAncestor(root, p, q);
console.log(result.val); // Output: 5
//这段代码实现了一个二叉树,并查找了两个指定节点 `p` 和 `q` 的最近公共祖先。

9、promise.all的实现 及 promise.all串行执行的实现

function customPromiseAll(promises) {
  return new Promise((resolve, reject) => {
    const results = [];
    let completedCount = 0;

    promises.forEach((promise, index) => {
      Promise.resolve(promise)
        .then((result) => {
          results[index] = result;
          completedCount++;

          if (completedCount === promises.length) {
            resolve(results);
          }
        })
        .catch(reject);
    });

    if (promises.length === 0) {
      resolve(results);
    }
  });
}

const promises = [
  Promise.resolve(1),
  Promise.resolve(2),
  Promise.resolve(3),
];

customPromiseAll(promises)
  .then((results) => {
    console.log(results); // Output: [1, 2, 3]
  })
  .catch((error) => {
    console.error(error);
  });

// 串行执行的 Promise.all
function customPromiseAllSerial(promises) {
  return promises.reduce((prev, current) => prev.then(current), Promise.resolve([]));
}

const serialPromises = [
  () => Promise.resolve(1),
  () => Promise.resolve(2),
  () => Promise.resolve(3),
];

customPromiseAllSerial(serialPromises)
  .then((results) => {
    console.log(results); // Output: [1, 2, 3]
  })
  .catch((error) => {
    console.error(error);
  });

10、输入一个n 返回一个1-n的全排列

function permute(n) {
  const result = [];
  const nums = Array.from({ length: n }, (_, index) => index + 1);

  function backtrack(start) {
    if (start === n) {
      result.push([...nums]);
      return;
    }

    for (let i = start; i < n; i++) {
      [nums[start], nums[i]] = [nums[i], nums[start]];
      backtrack(start + 1);
      [nums[start], nums[i]] = [nums[i], nums[start]];
    }
  }

  backtrack(0);
  return result;
}

const n = 3;
const permutations = permute(n);
console.log(permutations);
//这个函数使用回溯算法生成了 1 到 `n` 的全排

11、loash.get()方法的实现 输入各种字符串 返回对应的结果

function customGet(obj, path, defaultValue) {
  const keys = Array.isArray(path) ? path : path.split('.');
  let result = obj;

  for (const key of keys) {
    if (result && typeof result === 'object' && key in result) {
      result = result[key];
    } else {
      return defaultValue;
    }
  }

  return result;
}

const data = {
  user: {
    name: 'John',
    address: {
      city: 'New York',
    },
  },
};

const userName = customGet(data, 'user.name', 'Unknown');
console.log(userName); // Output: 'John'

const country = customGet(data, 'user.address.country', 'Unknown');
console.log(country); // Output: 'Unknown'
//`customGet()` 函数接受一个对象 `obj`,一个路径字符串或路径数组 `path`,以及一个可选的默认值 `defaultValue`,并返回指定路径的值,如果路径无效,则返回默认值。

12、jsonp的实现

function jsonp(url, callbackName, callback) {
  const script = document.createElement('script');
  script.src = `${url}?callback=${callbackName}`;
  document.body.appendChild(script);

  window[callbackName] = (data) => {
    callback(data);
    document.body.removeChild(script);
  };
}

// 使用示例
jsonp('https://example.com/api/data', 'myCallback', (data) => {
  console.log(data);
});

13、给定一个字符串 判断其中的括号是不是都能匹配上

function isParenthesesMatch(str) {
  const stack = [];
  const openingBrackets = '([{';
  const closingBrackets = ')]}';

  for (let char of str) {
    if (openingBrackets.includes(char)) {
      stack.push(char);
    } else if (closingBrackets.includes(char)) {
      if (stack.length === 0) {
        return false;
      }

      const lastOpenBracket = stack.pop();
      if (
        (char === ')' && lastOpenBracket !== '(') ||
        (char === ']' && lastOpenBracket !== '[') ||
        (char === '}' && lastOpenBracket !== '{')
      ) {
        return false;
      }
    }
  }

  return stack.length === 0;
}

console.log(isParenthesesMatch('()[]{}')); // true
console.log(isParenthesesMatch('(]')); // false
//这个函数会遍历输入字符串,将遇到的开括号入栈,然后在遇到闭括号时检查是否与栈顶的开括号匹配。如果括号都匹配,最终栈应为空。

14、sum(a,b,c,d) 用 sum(a)(b)(c,d).counter()实现

function removeAdjacentDuplicates(str) {
  return str.replace(/(.)\1+/g, '$1');
}

const input = 'aabbccd';
const result = removeAdjacentDuplicates(input);
console.log(result); // Output: 'abcd'

15、两个大数相加的实现

function addLargeNumbers(num1, num2) {
  const maxLen = Math.max(num1.length, num2.length);
  const result = [];
  let carry = 0;

  for (let i = 0; i < maxLen; i++) {
    const digit1 = num1[num1.length - 1 - i] || 0;
    const digit2 = num2[num2.length - 1 - i] || 0;
    const sum = digit1 + digit2 + carry;

    if (sum > 9) {
      carry = 1;
      result.unshift(sum - 10);
    } else {
      carry = 0;
      result.unshift(sum);
    }
  }

  if (carry > 0) {
    result.unshift(carry);
  }

  return result.join('');
}

const num1 = '123456789012345678901234567890';
const num2 = '987654321098765432109876543210';
const sum = addLargeNumbers(num1, num2);
console.log(sum);
//这个函数用于将两个大数相加,它将大数转化为数组并模拟手工相加的方式。

16、call apply bind的实现及原理

// 实现 call
Function.prototype.customCall = function (context, ...args) {
  context = context || window;
  const fnKey = Symbol();
  context[fnKey] = this;
  const result = context[fnKey](...args);
  delete context[fnKey];
  return result;
};

// 实现 apply
Function.prototype.customApply = function (context, args) {
  context = context || window;
  const fnKey = Symbol();
  context[fnKey] = this;
  const result = context[fnKey](...args);
  delete context[fnKey];
  return result;
};

// 实现 bind
Function.prototype.customBind = function (context, ...args) {
  context = context || window;
  const fnKey = Symbol();
  context[fnKey] = this;
  return function (...innerArgs) {
    const result = context[fnKey](...args, ...innerArgs);
    delete context[fnKey];
    return result;
  };
};

// 示例用法
const person = {
  name: 'John',
};

function greet(greeting) {
  console.log(`${greeting}, ${this.name}`);
}

greet.customCall(person, 'Hello'); // Output: 'Hello, John'
greet.customApply(person, ['Hi']); // Output: 'Hi, John'
const greetHi = greet.customBind(person, 'Hi');
greetHi(); // Output: 'Hi, John'

17、二叉树的之子形遍历

function zigzagLevelOrder(root) {
  if (!root) return [];

  const result = [];
  let isReverse = false;
  const queue = [root];

  while (queue.length) {
    const level = [];
    const levelSize = queue.length;

    for (let i = 0; i < levelSize; i++) {
      const node = queue.shift();
      if (isReverse) {
        level.unshift(node.val);
      } else {
        level.push(node.val);
      }
      if (node.left) queue.push(node.left);
      if (node.right) queue.push(node.right);
    }

    result.push(level);
    isReverse = !isReverse;
  }

  return result;
}

// 示例用法
const tree = {
  val: 3,
  left: {
    val: 9,
    left: null,
    right: null,
  },
  right: {
    val: 20,
    left: {
      val: 15,
      left: null,
      right: null,
    },
    right: {
      val: 7,
      left: null,
      right: null,
    },
  },
};

const result = zigzagLevelOrder(tree);
console.log(result); // Output: [[3], [20, 9], [15, 7]]
//这个函数实现了二叉树的之字形层序遍历,并返回一个数组,其中包含每层的节点值。

18、给定一个数组找出所有三个数之和为0的所有组合

function threeSum(nums) {
  const result = [];
  nums.sort((a, b) => a - b); // 先对数组排序

  for (let i = 0; i < nums.length - 2; i++) {
    if (i === 0 || (i > 0 && nums[i] !== nums[i - 1])) {
      let lo = i + 1;
      let hi = nums.length - 1;
      const sum = 0 - nums[i];

      while (lo < hi) {
        if (nums[lo] + nums[hi] === sum) {
          result.push([nums[i], nums[lo], nums[hi]]);
          while (lo < hi && nums[lo] === nums[lo + 1]) lo++;
          while (lo < hi && nums[hi] === nums[hi - 1]) hi--;
          lo++;
          hi--;
        } else if (nums[lo] + nums[hi] < sum) {
          lo++;
        } else {
          hi--;
        }
      }
    }
  }

  return result;
}

const nums = [-1, 0, 1, 2, -1, -4];
const result = threeSum(nums);
console.log(result); // Output: [[-1, -1, 2], [-1, 0, 1]]

19、二分查找

function binarySearch(arr, target) {
  let left = 0;
  let right = arr.length - 1;

  while (left <= right) {
    const mid = Math.floor((left + right) / 2);
    if (arr[mid] === target) {
      return mid;
    } else if (arr[mid] < target) {
      left = mid + 1;
    } else {
      right = mid - 1;
    }
  }

  return -1;
}

const sortedArray = [1, 3, 5, 7, 9, 11, 13, 15];
const target = 7;
const index = binarySearch(sortedArray, target);
console.log(index); // Output: 3

20、两个矩形相交处 输入 2个矩形的4个坐标

function isRectangleOverlap(rect1, rect2) {
  return (
    rect1[2] > rect2[0] && // rect1 right > rect2 left
    rect1[0] < rect2[2] && // rect1 left < rect2 right
    rect1[3] > rect2[1] && // rect1 bottom > rect2 top
    rect1[1] < rect2[3] // rect1 top < rect2 bottom
  );
}

const rect1 = [0, 0, 2, 2];
const rect2 = [1, 1, 3, 3];
const overlap = isRectangleOverlap(rect1, rect2);
console.log(overlap); // Output: true

21、两个有序链表的合并

class ListNode {
  constructor(val) {
    this.val = val;
    this.next = null;
  }
}

function mergeTwoLists(l1, l2) {
  const dummyHead = new ListNode(0);
  let current = dummyHead;

  while (l1 !== null && l2 !== null) {
    if (l1.val < l2.val) {
      current.next = l1;
      l1 = l1.next;
    } else {
      current.next = l2;
      l2 = l2.next;
    }
    current = current.next;
  }

  if (l1 !== null) {
    current.next = l1;
  } else {
    current.next = l2;
  }

  return dummyHead.next;
}

// 示例用法
const l1 = new ListNode(1);
l1.next = new ListNode(2);
l1.next.next = new ListNode(4);

const l2 = new ListNode(1);
l2.next = new ListNode(3);
l2.next.next = new ListNode(4);

const mergedList = mergeTwoLists(l1, l2);
console.log(mergedList);

22、let arr = [{ id: '1', name: "河北省", children: [{ id: '1-1', name: "石家庄市", children: [{ id: '1-1-1', name: "新华区", }, { id: '1-1-2', name: "裕华区", }] }, { id: '1-2', name: "唐山市", children: [{ id: '1-2-1', name: "路北区", }, { id: '1-2-2', name: "路南区", }] }] // 实现函数 findAdrress(arr, id) 返回地址的拼接 比如 findAdrress(arr, '1-2-1') 返回河北省唐山市路北区

function findAddress(arr, id) {
  for (const item of arr) {
    if (item.id === id) {
      return item.name;
    }
    if (item.children) {
      const result = findAddress(item.children, id);
      if (result) {
        return item.name + result;
      }
    }
  }
  return null;
}

const addressData = [
  {
    id: '1',
    name: '河北省',
    children: [
      {
        id: '1-1',
        name: '石家庄市',
        children: [
          { id: '1-1-1', name: '新华区' },
          { id: '1-1-2', name: '裕华区' },
        ],
      },
      {
        id: '1-2',
        name: '唐山市',
        children: [
          { id: '1-2-1', name: '路北区' },
          { id: '1-2-2', name: '路南区' },
        ],
      },
    ],
  },
];

const result = findAddress(addressData, '1-2-1');
console.log(result); // Output: '河北省唐山市路北区'
//这个函数用于查找嵌套对象数组 `arr` 中的地址,根据给定的 `id`,返回地址的拼接字符串。

24、输入一个字符串返回最长回文

function longestPalindrome(s) {
  if (s.length < 2) return s;

  let start = 0;
  let maxLength = 1;

  function expandAroundCenter(left, right) {
    while (left >= 0 && right < s.length && s[left] === s[right]) {
      const currentLength = right - left + 1;
      if (currentLength > maxLength) {
        maxLength = currentLength;
        start = left;
      }
      left--;
      right++;
    }
  }

  for (let i = 0; i < s.length - 1; i++) {
    expandAroundCenter(i, i); // odd length
    expandAroundCenter(i, i + 1); // even length
  }

  return s.slice(start, start + maxLength);
}

const input = 'babad';
const result = longestPalindrome(input);
console.log(result); // Output: 'bab' or 'aba'
//这个函数使用中心扩展法来查找输入字符串 `s` 中的最长回文子串。

25、输入一个字符串返回最长无重复子串

function lengthOfLongestSubstring(s) {
  const n = s.length;
  let maxLength = 0;
  const charMap = new Map();
  let left = 0;

  for (let right = 0; right < n; right++) {
    if (charMap.has(s[right]) && charMap.get(s[right]) >= left) {
      left = charMap.get(s[right]) + 1;
    }
    charMap.set(s[right], right);
    maxLength = Math.max(maxLength, right - left + 1);
  }

  return maxLength;
}

const input = 'abcabcbb';
const result = lengthOfLongestSubstring(input);
console.log(result); // Output: 3 (for 'abc')

26、翻转链表

class ListNode {
  constructor(val) {
    this.val = val;
    this.next = null;
  }
}

function reverseList(head) {
  let prev = null;
  let current = head;

  while (current !== null) {
    const next = current.next;
    current.next = prev;
    prev = current;
    current = next;
  }

  return prev;
}

// 示例用法
const head = new ListNode(1);
head.next = new ListNode(2);
head.next.next = new ListNode(3);
head.next.next.next = new ListNode(4);
head.next.next.next.next = new ListNode(5);

const reversedHead = reverseList(head);
console.log(reversedHead);
//这个函数用于翻转链表,返回一个新的链表头。

27、判断链接是否有环及环的入口

class ListNode {
  constructor(val) {
    this.val = val;
    this.next = null;
  }
}

function detectCycle(head) {
  let slow = head;
  let fast = head;

  while (fast !== null && fast.next !== null) {
    slow = slow.next;
    fast = fast.next.next;

    if (slow === fast) {
      let entry = head;
      while (entry !== slow) {
        entry = entry.next;
        slow = slow.next;
      }
      return entry;
    }
  }

  return null;
}

// 示例用法
const head = new ListNode(3);
const node1 = new ListNode(2);
const node2 = new ListNode(0);
const node3 = new ListNode(-4);

head.next = node1;
node1.next = node2;
node2.next = node3;
node3.next = node1; // 创建循环

const entry = detectCycle(head);
console.log(entry); // Output: node1
//这个函数用于判断链表是否有环,如果有环则返回环的入口节点。

28、多维数组展示为一维

function flattenArray(arr) {
  return arr.reduce((acc, val) => Array.isArray(val) ? acc.concat(flattenArray(val)) : acc.concat(val), []);
}

const multiDimensionalArray = [1, [2, [3, 4], 5], 6];
const flattenedArray = flattenArray(multiDimensionalArray);
console.log(flattenedArray); // Output: [1, 2, 3, 4, 5, 6]
这个函数会将多维数组 `arr` 展平为一维数组

29、单个字符组成的数组统计每一个字符出现的次数

function countCharacters(arr) {
  const charCount = {};

  for (const char of arr) {
    if (charCount[char]) {
      charCount[char]++;
    } else {
      charCount[char] = 1;
    }
  }

  return charCount;
}

const charArray = ['a', 'b', 'a', 'c', 'b', 'a'];
const characterCount = countCharacters(charArray);
console.log(characterCount); // Output: { 'a': 3, 'b': 2, 'c': 1 }
//这个函数会统计数组 `arr` 中每个字符出现的次数并返回一个对象。

30、自己实现promise

class MyPromise {
  constructor(executor) {
    this.state = 'pending';
    this.value = undefined;
    this.callbacks = [];

    const resolve = (value) => {
      if (this.state === 'pending') {
        this.state = 'fulfilled';
        this.value = value;
        this.callbacks.forEach((callback) => callback.onFulfilled(value));
      }
    };

    const reject = (reason) => {
      if (this.state === 'pending') {
        this.state = 'rejected';
        this.value = reason;
        this.callbacks.forEach((callback) => callback.onRejected(reason));
      }
    };

    try {
      executor(resolve, reject);
    } catch (error) {
      reject(error);
    }
  }

  then(onFulfilled, onRejected) {
    if (this.state === 'fulfilled') {
      onFulfilled(this.value);
    } else if (this.state === 'rejected') {
      onRejected(this.value);
    } else {
      this.callbacks.push({
        onFulfilled,
        onRejected,
      });
    }
  }
}

// 示例用法
const promise = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve('Hello, world!');
  }, 1000);
});

promise.then(
  (value) => {
    console.log(value); // Output: 'Hello, world!'
  },
  (reason) => {
    console.error(reason);
  }
);
//这个示例只是 Promise 的一个极简化版本,用于演示 Promise 的核心概念。实际的 Promise 实现更加复杂,包括处理异步操作、链式调用等功能。

31、开方的实现

const number = 16;
const squareRoot = Math.sqrt(number);
console.log(squareRoot); // Output: 4
//这个方法会返回输入数字的平方根

32、斐波那契数列的实现

递归实现:
function fibonacciRecursive(n) {
  if (n <= 1) {
    return n;
  }
  return fibonacciRecursive(n - 1) + fibonacciRecursive(n - 2);
}

const n = 10;
console.log(fibonacciRecursive(n)); // Output: 55
迭代实现:
function fibonacciIterative(n) {
  let a = 0;
  let b = 1;

  for (let i = 2; i <= n; i++) {
    const temp = a + b;
    a = b;
    b = temp;
  }

  return b;
}

const n = 10;
console.log(fibonacciIterative(n)); // Output: 55

33、防抖和节流的实现

function debounce(func, delay) {
  let timeout;
  return function (...args) {
    clearTimeout(timeout);
    timeout = setTimeout(() => {
      func.apply(this, args);
    }, delay);
  };
}

// 示例用法
function handleInput() {
  console.log('Debounced input event');
}

const debouncedInput = debounce(handleInput, 300);

// 在输入框中触发事件,但处理程序会在 300 毫秒后执行
function throttle(func, delay) {
  let lastExecTime = 0;
  return function (...args) {
    const currentTime = Date.now();
    if (currentTime - lastExecTime >= delay) {
      func.apply(this, args);
      lastExecTime = currentTime;
    }
  };
}

// 示例用法
function handleScroll() {
  console.log('Throttled scroll event');
}

const throttledScroll = throttle(handleScroll, 300);

// 当滚动事件触发时,处理程序每 300 毫秒执行一次

35、实现数组的map方法

function customMap(arr, callback) {
  const result = [];
  for (let i = 0; i < arr.length; i++) {
    result.push(callback(arr[i], i, arr));
  }
  return result;
}

const numbers = [1, 2, 3, 4, 5];
const doubled = customMap(numbers, (num) => num * 2);
console.log(doubled); // Output: [2, 4, 6, 8, 10]
//这个 `customMap` 函数接受一个数组和一个回调函数,将回调函数应用于数组的每个元素,并返回一个新的数组。在示例中,`doubled` 数组包含了 `numbers` 数组中每个元素的两倍值