You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
5.1 KiB
5.1 KiB
Undefined
- underfined 实际上是一个变量而并非是一个关键字,这是 JavaScript 的一个设计失误,为了避免无形中被修改,建议使用 void 0
- 在 ES5 后,underfined 在全局作用域中被设置为 read-only,但是在局部作用域中,还是会被修改
String
- JavaScript 中的字符串是永远无法变更的,一旦字符被构建出来,无法用任何方式改变字符串的内容
- Example:
let testString = "Hello"; testString[0] = "X"; console.log(testString);
Number
- JavaScript 中的 Number 类型有 18437736874454810627(即 2^64-2^53+3) 个值
- NaN其实是 2^53-2 个特殊数字的合集,NaN并不是一个数,而是一堆数据合集,所以NaN ! == NaN
- 在 JavaScript 中
0.1 + 0.2 !== 0.3
,这是因为对于硬件系统来说,由高低电平表示1和0,这样我们使用的高级语言都要用二进制进行编码,不同的进制数在转换的时候都会有精度的问题,所以相加之后因为一些误差就导致值不相等 - 在比较浮点数的时候,不应该使用等于或者全等,应该使用 JavaScript 提供的最小精度值 :
(Math.abs(0.1 + 0.2 - 0.3) <= Number.EPSILON)
Object
- JavaScript 中的几个基本类型,都在对象类型中有一个对应的对象类型,这些基本类型是
Number
、String
、Boolean
、Symbol
- 所以 3 与 new Number(3) 是完全不同的值,一个是 Number 类型,一个是对象类型
Number
、String
、Boolean
,三个构造器是两用的,当和 new 搭配时会产生对象,直接调用时表示强制类型转换- Symbol 函数比较特殊,直接用 new 调用它会抛出错误,但它仍然是 Symbol 对象的构造器
- JavaScript 语言在设计上视图模糊对象和基本类型之间的关系,代码中可以把对象的方法放在基本类型上使用比如
"Hello".charAt(0)
- 这是因为 JavaScript 运算符提供了装箱操作,它会根据基础类型构造一个临时对象,使得我们能在基础类型上调用对象类型的方法
- JavaScript高级程序设计中的解释: 为了方便操作原始值,ES提供了3种特殊的引用类型:Boolean、Number和String。这些类型具有其他引用类型一样的特点,但也具有与各自原始类型对应的特殊行为。每当用到某个原始值的方法和属性时,后台都会创建一个相应的原始包装类型的对象,从而暴露出操作原始值的各种方法。
- 围绕原始数据类型创建一个显式包装器对象从 ECMAScript 6 开始不再被支持。 然而,现有的原始包装器对象,如 new Boolean、new String以及new Number,因为遗留原因仍可被创建
类型转换
- 在使用 parseInt 的时候,建议传入 parseInt 的第二个参数
- parseFloat 则直接把原字符串作为十进制来解析,它不会引入任何的其他进制
- 多数情况下,Number 是比 parseInt 和 parseFloat 更好的选择
- Object.prototype.toString.call() 能识别类型是因为其内部发生了装箱转换,
装箱转换
- 每一种基本类型 Number、String、Boolean、Symbol 在对象中都有对应的类,所谓装箱转换,正是把基本类型转换为对应的对象,它是类型转换中一种相当重要的种类
- 全局的 Symbol 函数无法使用 new 来调用,但我们仍可以利用装箱机制来得到一个 Symbol 对象,我们可以利用一个函数的 call 方法来强迫产生装箱
var symbolObject = (function(){ return this; }).call(Symbol("a"));
console.log(typeof symbolObject); //object
object console.log(symbolObject instanceof Symbol); //true
console.log(symbolObject.constructor == Symbol); //true
- 装箱机制会频繁产生临时对象,在一些对性能要求较高的场景下,我们应该尽量避免对基本类型做装箱转换
- call 本身会产生装箱操作,所以需要配合 typeof 来区分基本类型还是对象类型,因 call 当传入值为基本类型时,会触发这个基本类型的对应的类,所以用
object.prototype.tostring
不正确,如果是对象则可以用此方法得出该实例的类
拆箱转换
- 在 JavaScript 标准中,规定了 ToPrimitive 函数,它是对象类型到基本类型的转换(即,拆箱转换)
- 拆箱转换会尝试调用 valueOf 和 toString 来获得拆箱后的基本类型。如果 valueOf 和 toString 都不存在,或者没有返回基本类型,则会产生类型错误 TypeError
var o = {
valueOf : () => {console.log("valueOf"); return {}},
toString : () => {console.log("toString"); return {}}
}
o * 2
// valueOf
// toString
// TypeError 拆箱失败
- 到 String 的拆箱转换会优先调用 toString。我们把刚才的运算从 o x 2 换成 String(o),那么你会看到调用顺序就变了
- 在 ES6 之后,还允许对象通过显式指定 @@toPrimitive Symbol 来覆盖原有的行为。
var o = {
valueOf : () => {console.log("valueOf"); return {}},
toString : () => {console.log("toString"); return {}}
}
o[Symbol.toPrimitive] = () => {console.log("toPrimitive"); return "hello"}
console.log(o + "")
// toPrimitive
// hello