关于JS你该知道的(错误)和不知道的(技巧)

2025-03-25T14:42:53+08:00 | 3分钟阅读 | 更新于 2025-03-25T14:42:53+08:00

Macro Zhao

关于JS你该知道的(错误)和不知道的(技巧)

你该知道的(容易犯的错误)

  1. 忽略异步函数
// Incorrect: Ignoring the asynchronous nature of setTimeout
console.log("Start");
setTimeout(() => console.log("Timeout"), 0);
console.log("End");

// Correct: Understanding and handling asynchronous code
console.log("Start");
setTimeout(() => console.log("Timeout"), 0);
Promise.resolve().then(() => console.log("Promise"));
console.log("End");
  1. 错误的作用域
// Incorrect: Variable declared without proper scoping
function incorrectScope() {
  for (var i = 0; i < 5; i++) {
    // 'i' is now global, not local to the loop
  }
  console.log(i); // Outputs 5
}

// Correct: Using 'let' for block-scoped variables
function correctScope() {
  for (let i = 0; i < 5; i++) {
    // 'i' is local to the loop block
  }
  // console.log(i); // Error: 'i' is not defined
}
  1. 内存泄露
// Incorrect: Creating a memory leak with event listeners
function createMemoryLeak() {
  const element = document.getElementById("myElement");
  element.addEventListener("click", function handleClick() {
    // Some logic
  });
  // Forgot to remove the event listener
}

// Correct: Removing event listeners to avoid memory leaks
function avoidMemoryLeak() {
  const element = document.getElementById("myElement");
  function handleClick() {
    // Some logic
  }
  element.addEventListener("click", handleClick);
  // Remove the event listener when it's no longer needed
  // element.removeEventListener("click", handleClick);
}
  1. 未处理异常错误
// Incorrect: Inadequate error handling
function fetchData() {
  try {
    // Fetch data from an API
    fetch("https://api.example.com/data")
      .then(response => response.json())
      .then(data => console.log(data))
      .catch(error => console.log(error.message));
  } catch (error) {
    console.log("Error occurred:", error.message); // This won't catch fetch errors
  }
}

// Correct: Proper error handling with fetch
async function fetchDataCorrect() {
  try {
    const response = await fetch("https://api.example.com/data");
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error("Error occurred:", error.message);
  }
}
  1. 忽略浏览器兼容性
// Incorrect: Assuming browser features work uniformly
document.getElementById("myElement").remove(); // Not supported in some older browsers

// Correct: Checking for feature support before usage
const element = document.getElementById("myElement");
if (element && element.remove) {
  element.remove();
} else {
  // Fallback or alternative approach
  element.parentNode.removeChild(element);
}
  1. 笨重的响应
// Incorrect: Relying solely on a framework without understanding basics
const element = React.createElement("div", null, "Hello, World!");
ReactDOM.render(element, document.getElementById("root"));

// Correct: Understanding the framework and underlying principles
const element = <div>Hello, World!</div>;
ReactDOM.render(element, document.getElementById("root"));
  1. 低性能的代码
// Incorrect: Inefficient use of loops
const array = [1, 2, 3, 4, 5];
for (let i = 0; i < array.length; i++) {
  console.log(array[i]);
}

// Correct: Using forEach for better performance
const array = [1, 2, 3, 4, 5];
array.forEach(item => console.log(item));
  1. 垃圾注释
// Incorrect: Lack of comments and documentation
function calculateTotal(price, quantity) {
  return price * quantity;
}

// Correct: Adding meaningful comments for better understanding
/**
 * Calculates the total cost based on the given price and quantity.
 * @param {number} price - The unit price of the item.
 * @param {number} quantity - The quantity of items.
 * @returns {number} The total cost.
 */
function calculateTotal(price, quantity) {
  return price * quantity;
}

你不知道的(qi技yin巧)

  1. 使用别名进行解构 解构赋值是一个强大的功能。您知道可以在赋值期间为变量添加别名吗?
const { prop1: newName1, prop2: newName2 } = object;

在这里,我们将prop1和分别重命名prop2newName1newName2

  1. 内存缓存以提高性能 内存缓存是一种缓存函数结果以获得更好性能的技术。这是一个简单的实现:
const memoizedFunction = (function () {
  const cache = {};
  return function (args) {
    if (!(args in cache)) {
      cache[args] = computeResult(args);
    }
    return cache[args];
  };
})();

通过缓存结果,我们避免了冗余计算。

  1. 函数组合的柯里化 柯里化允许创建可重用和可组合的函数。看看这个简洁的柯里化函数:
const curry = (fn, ...args) =>
  args.length >= fn.length ? fn(...args) : (...moreArgs) => curry(fn, ...args, ...moreArgs);

这样,您可以轻松创建部分应用的函数。

  1. 去抖和节流 控制函数执行的速率至关重要。使用去抖和节流来有效处理频繁事件。
const debounce = (func, delay) => {
  let timeoutId;

  return function (...args) {
    const context = this;

    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => {
      func.apply(context, args);
    }, delay);
  };
};

const throttle = (func, interval) => {
  let lastExecTime = 0;
  let timeoutId;

  return function (...args) {
    const context = this;
    const currentTime = new Date().getTime();

    if (currentTime - lastExecTime >= interval) {
      func.apply(context, args);
      lastExecTime = currentTime;
    } else {
      clearTimeout(timeoutId);
      timeoutId = setTimeout(() => {
        func.apply(context, args);
        lastExecTime = currentTime;
      }, interval - (currentTime - lastExecTime));
    }
  };
};

这些技术可以防止过多的函数调用,从而提高性能。

  1. 动态对象键 使用方括号表示法动态创建对象键:
const dynamicKey = 'key';
const obj = { [dynamicKey]: 'value' };

当密钥在运行时确定时,这很方便。

  1. 可选链接 可选链接简化了嵌套属性的访问,无需进行大量检查。
// Noobs:
let nestedValue;
if (object && object.property && object.property.nested) {
  nestedValue = object.property.nested;
} else {
  nestedValue = 'default';
}

// Pro:
let nestedValue = object?.property?.nested ?? 'default';

这有助于防止“无法读取未定义的‘嵌套’属性”错误,并使代码更加简洁。

  1. 箭头函数 箭头函数提供了定义函数的简洁语法。
// Noobs:
function add(a, b) {
  return a + b;
}

// Pro:
const add = (a, b) => a + b;

箭头函数对于简短的匿名函数特别有用。

  1. 数组解构 解构不仅仅适用于对象;也适用于对象。它也适用于数组!
// Noobs:
const array = [1, 2, 3];
const first = array[0];
const second = array[1];

// Pro:
const [first, second] = [1, 2, 3];

这使得数组元素的处理更加简单。

  1. 对象解构 与数组解构类似,此技术用于对象。
// Noobs:
const user = { name: 'John', age: 30 };
const name = user.name;
const age = user.age;

// Pro:
const { name, age } = { name: 'John', age: 30 };

解构对象以简洁地提取值。

  1. 验证代理 使用代理对象进行输入验证。
const validator = new Proxy({}, {
  set: function (target, prop, value) {
    if (prop === 'age' && typeof value !== 'number') {
      throw new Error('Age must be a number.');
    }
    target[prop] = value;
  }
});

代理可以拦截和验证属性分配,提供强大的输入控制。

OK

现在已经探索了 10 个高级 JavaScript 技巧。花时间尝试每一种并将它们集成到您的编码工具包中。

© 2011 - 2025 Macro Zhao的分享站

关于我

如遇到加载502错误,请尝试刷新😄

Hi,欢迎访问 Macro Zhao 的博客。Macro Zhao(或 Macro)是我在互联网上经常使用的名字。

我是一个热衷于技术探索和分享的IT工程师,在这里我会记录分享一些关于技术、工作和生活上的事情。

我的CSDN博客:
https://macro-zhao.blog.csdn.net/

欢迎你通过评论或者邮件与我交流。
Mail Me

推荐好玩(You'll Like)
  • AI 动·画
    • 这是一款有趣·免费的能让您画的画中的角色动起来的AI工具。
    • 支持几十种动作生成。
我的项目(My Projects)
  • 爱学习网

  • 小乙日语App

    • 这是一个帮助日语学习者学习日语的App。
      (当然初衷也是为了自用😄)
    • 界面干净,简洁,漂亮!
    • 其中包含 N1 + N2 的全部单词和语法。
    • 不需注册,更不需要订阅!完全免费!
  • 小乙日文阅读器

    • 词汇不够?照样能读日语名著!
    • 越读积累越多,积跬步致千里!
    • 哪里不会点哪里!妈妈再也不担心我读不了原版读物了!
赞助我(Sponsor Me)

如果你喜欢我的作品或者发现它们对你有所帮助,可以考虑给我买一杯咖啡 ☕️。这将激励我在未来创作和分享更多的项目和技术。🦾

👉 请我喝一杯咖啡

If you like my works or find them helpful, please consider buying me a cup of coffee ☕️. It inspires me to create and share more projects in the future. 🦾

👉 Buy me a coffee