函数表达式和函数声明
// 函数声明语句
foo(); // ok
function foo() {}
// 函数表达式语句
foo(); // Uncaught TypeError: foo is not a function
var foo = function() {}
函数声明,会在执行当前作用域的代码之前执行完毕。
而函数表达式,只有处理器真正遇到这段代码的时候才会执行。
.sort() 的默认行为
arr = [11, 10, 3, 2, 1]
arr.sort() // [1, 10, 11, 2, 3]
默认情况下,sort() 会将元素转换成字符串,然后对字符串进行升序排序🤧。
如果要对数字进行排序,需要传入自定义的对比函数。
arr = [11, 10, 3, 2, 1]
arr.sort((a, b) => a - b) // [1, 2, 3, 10, 11]
0.1 + 0.2 ≠ 0.3
0.1 + 0.2 // => 0.30000000000000004
0.1 + 0.2 === 0.3 // => false
这不是 JavaScript 才有的问题,只要是根据 IEEE 754 标准实现的浮点数运算,都会有这个问题。
因为计算机是用二进制来记录数据的, 0.1 转换成二进制变成了 0.0001100110011...(0011无限循环),假设计算时,只保留小数点后4位的话(实际上会保留更多位,但本质是一样的),就变成了 0.0001,此时已经损失了一部分精度,在此基础上进行计算的话,最终的结果和 0.3 就会存在偏差。
如果需要对比小数,可以选择一个具体的精度,对比两数的差值是否在想要的精度范围内。
const PRECISION = 1e-7;
if (Math.abs(a - b) < PRECISION) {
// a,b 的小数点后 7 位都是相等的
}
反直觉的 ==
'' == [] // true
[] == [] // false
NaN == NaN // false
javascript 同时提供了 === 和 == ,用于对比数据(当然还有 Object.is())。
=== 同时判断数据的类型和数据的值,只有两者都相等的时候才会返回 true 。
== 有自己的一套判断规则,根据参与判断的数据类型,还有可能自动进行数据类型转换,再对比转换后的值。具体的规则虽然不复杂,但数量多(因为类型多),具体的规则参阅文档:
262.ecma-international.org/5.1/#sec-11…
像 [] == [] 便是根据规则:
(1)首先判断 x 和 y 的类型相等
(1.f)然后判断两者并非引用同一个对象,返回 false
自动加分号
function foo() {
return {
name: 'apple'
}
}
function bar() {
return
{
name: 'orange'
}
}
foo(); // {name: 'apple'}
bar(); // undefined
bar() 之所以返回 undefined,是因为实际运行的代码是这样子的:
function bar() {
return;
{
name: 'orange'
}
}
return 语句后面被自动加上了分号 ;
所以,平时书写的 JS 代码的时候,推荐主动加上分号,避免不必要的麻烦。
总结
JavaScript 是一门弱类型的脚本语言,跟 C++,Java 等强类型语言比较起来,语法可以说是非常的自由奔放。使用一个变量,不需要提前声明变量的类型。不同数据类型的变量,也可以进行加减乘除的运算(出现了奇奇怪怪的面试题🙄)。 作为一门发展了十几年的语言,JavaScript 在变得越来越好的同时,也有不少历史遗留问题,作为开发者我们还是要注意一下。