1.typeof null == 'object'
typeof null返回'object'是JavaScript中存在的一个Bug,正确返回的结果应该是'null',这个Bug已经存在了近二十多年,修复他牵涉到很多web应用。
原因:在JavaScript中对象在底层标识为二进制,在JavaScript中二进制前三位0的话,会判断为object类型,null的二进制表示是全0.所以typeof 时会返回object。
2.判断数值相等
JavaScript中只有一种数值类型,就是64位双精度,并没有真正意义上的整数。浮点数计算不一定准确,二进制浮点数中的0.1和0.2并不是十分精确。0.1 + 0.2 !== 0.3 。判断0.1 + 0.2和0.3是否相等,最常见的方法是设置一个误差,通常称为机器精度 ,对于JavaScript来说,通常是 2^-52次方
function demo(n1,n2){
if(!Number.EPSILON){
Number.EPSILON = Mathpow(2,-52)
}
return Mathabs(n1 - n2) < Number.EPSILON
}
3.判断NaN
NaN不是数字的数字,一个警戒值,用于指出数字类型的中的错误情况,既数学运算没有成功,失败后返回的结果。NaN是唯一一个非自反的值 NaN !== NaN // true。怎么判断是不是NaN呢?使用isNaN的话你就上当了,因为isNaN('str') == true。 这是JavaScript中一个bug,存在已经超过19年。
// 方法1
x!== x
// 方法2 ES6的API
Number.isNaN(x)
4.区分函数声明和表达式
这个其实非常好区别,function是第一个词语就是函数声明,否则是表达式。
区别:
- 函数声明会被提升到当前作用域的顶部
- 函数声明需要命名,而函数表达式可以选择命名或者使用匿名函数
一个技巧: 使用函数表达式时,应当给函数命名,报错的时候,容易快速找到位置。
5.new调用一个函数会发生什么
new调用的函数就是构造函数,new 调用一个函数大致的步骤:
- 创建一个空对象{}
- 将空对象的【prototype】属性指向 构造函数.prototype
- 执行函数体,并将this绑定到对象上
- 如果函数返回对象或者数组类型,则返回改值。否则返回创建的对象
6.零值
在JavaScript中有一个 +0 和一个-0。 0 乘或除 一个负数就会得到-0,JSON.parse('-0')也会得到-0。实际开发中没用。
判断0和-0
1 / 0 // Infinity
1 / -0 // -Infinity
7.模仿类
JavaScript中实际上没有类,(ES6)引入了 class 关键字来简化对象的创建,但它仍然是基于原型的语法糖,底层仍然是通过原型来实现对象的行为与属性的共享,因此,从 JavaScript 语言的底层机制来看,JavaScript 并没有传统意义上的类的概念。但是,借助原型和构造函数的组合使用,我们可以在 JavaScript 中模拟类的行为,并实现对象之间的继承关系。
// 使用 原型继承 和 构造函数 “模仿类”
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function() { console.log("Hello, my name is " + this.name); };
var person1 = new Person("Alice", 25);
var person2 = new Person("Bob", 30);
person1.sayHello(); // 输出:Hello, my name is Alice
person2.sayHello(); // 输出:Hello, my name is Bob
JavaScript中使用模仿类写出来的代码奇丑无比,关系混乱,使用模仿类有可能得不偿失
8.抽象相等 ==
-
字符串和数字之间的相等比较,会把字符串toNumber之后做对比
-
其他类型和布尔类型的相等比较
2.1 数字和布尔类型,会把布尔类型toNumber之后对比
2.2 字符串和布尔类型,会都转为数字后对比
注意:避免使用布尔值的宽松相等 xx == true / xx == false
-
undefined和null仅余null和undefined抽象相等,除此之外的值都不成立。包括false 0这些假值
-
对象和非对象之间,会把对象ToPrimitive后对比