返回

JavaScript 的那些怪事

前端

序言
JavaScript 是一种有趣且强大的编程语言,它充满了惊喜。在本文中,我们将探讨一些 JavaScript 中最奇怪的事情,从函数表达式和函数声明的差异到 sort() 方法的默认行为。我们还将揭开 JavaScript 中一些最令人困惑的行为背后的原因。

函数表达式和函数声明

函数表达式和函数声明是 JavaScript 中定义函数的两种方式。函数声明,会在执行当前作用域的代码之前执行完毕。而函数表达式,只有处理器真正遇到这段代码的时候才会执行。

函数声明的语法如下:

function functionName(parameters) {
  // 函数体
}

函数表达式的语法如下:

const functionName = (parameters) => {
  // 函数体
};

函数声明和函数表达式的主要区别在于函数声明会在执行当前作用域的代码之前执行完毕,而函数表达式只有处理器真正遇到这段代码的时候才会执行。这会导致一些有趣的后果。

例如,以下代码将不会抛出错误:

function sayHello() {
  console.log("Hello!");
}

sayHello();

但是,以下代码会抛出错误:

const sayHello = () => {
  console.log("Hello!");
};

sayHello();

这是因为在执行 sayHello() 时,函数表达式还没有被执行,因此 sayHello 变量还没有被赋值。

sort() 方法的默认行为

sort() 方法是 JavaScript 中用于对数组进行排序的方法。sort() 方法的默认行为是将数组中的元素转换为字符串,然后按照字符串的 Unicode 代码点进行排序。

这会导致一些意想不到的结果。例如,以下代码将输出 [10, 2, 3, 4, 5]:

const numbers = [10, 2, 3, 4, 5];
numbers.sort();
console.log(numbers);

这是因为 sort() 方法将数组中的数字转换为字符串,然后按照字符串的 Unicode 代码点进行排序。因此,数字 10 被排在了第一位,因为它的 Unicode 代码点是 49,而数字 2 被排在了第二位,因为它的 Unicode 代码点是 50。

为了避免这种情况,我们可以使用 sort() 方法的第二个参数。sort() 方法的第二个参数是一个比较函数,它用于比较数组中的两个元素。我们可以使用比较函数来指定如何对数组中的元素进行排序。

例如,以下代码将输出 [2, 3, 4, 5, 10]:

const numbers = [10, 2, 3, 4, 5];
numbers.sort((a, b) => a - b);
console.log(numbers);

这是因为我们使用了一个比较函数来指定如何对数组中的元素进行排序。比较函数将数组中的两个元素相减,如果结果为负数,则将第一个元素排在前面。如果结果为正数,则将第二个元素排在前面。如果结果为 0,则两个元素保持原有顺序。

其他令人困惑的行为

JavaScript 中还有一些其他令人困惑的行为,例如:

  • == 和 === 的区别:== 和 === 都是比较运算符,但它们的行为不同。== 比较两个值是否相等,而 === 比较两个值是否严格相等。例如,1 == "1" 为 true,但 1 === "1" 为 false。
  • 闭包:闭包是一个函数及其执行环境的结合。闭包允许函数访问它被创建时的局部变量,即使这些局部变量已经超出了作用域。这会导致一些有趣的后果,例如,可以创建函数来访问另一个函数的局部变量。
  • this this 指向当前执行上下文的对象。this 关键字的值取决于函数的调用方式。例如,当一个函数作为对象的方法调用时,this 关键字的值是该对象。当一个函数作为独立函数调用时,this 关键字的值是 window 对象。

结论

JavaScript 是一门有趣且强大的编程语言,但它也有一些奇怪的地方。了解这些奇怪的地方可以帮助我们避免错误,并编写出更好的代码。