值类型和引用类型
原始类型(alias: 值类型,基础类型) primitive: string number boolean null undefined symbol
引用类型: Object 其他内置Object派送类型 Array Function Map Set WeakMap WeakSet RegExp
NaN: 特殊的 Number 类型,IsNaN() 判断一个值是否为 NaN
- 引用类型可以有属性和方法,而基础类型是不可以的
- 为什么
'text'.length可以访问到'text'的length属性?→ 包装类
- 为什么
包装类
String Number Boolean Symbol
new String('') 和 String('') 的区别
new String('')构造一个String实例, 得到的是一个对象;let a = new String('a'); let b = new String('b'),a和b是不相等的,ab保存的是两个不同的引用地址- 直接调用
String函数的话是会执行类型转换,这个函数返回的就是一个值类型的string;String(1)返回值是'1'
'text'.length 能够工作的原因
通过 .(术语:属性访问器Property Accessor) 访问值类型 'text' 的 length 属性时, 会发生类型转换(装箱),值类型的 'text' 会转换为引用类型的 String 实例(相当与 new String('text')), 然后这个 String 实例的 length 属性会被返回;
每次访问一个 string 值类型的属性时,都会 new 一个新的 String 包装类,返回这个包装类实例对应的属性值,返回后这个包装类的实例就会立即被丢弃
Number Boolean 同理, Symbol 比较特殊, new Symbol 会抛出 TypeError, 详见下文 → Symbol
值类型转换为引用类型(ToObject)的逻辑 → TC39 - sec-toobject
![[Pasted image 20230423221514.png]]
Symbol
Symbol 是一个比较特殊的包装类, 因为无法通过 new 操作符创建 Symbol 实例
通常直接通过 Symbol('bar') 函数创建值类型的 symbol
Symbol(key: string) 不论传入的参数 key 是什么,都会保证返回唯一的 symbol 值类型, 也就是通过 Symbol(key: string) 函数创建的每个 symbol 都是不相等的
let s = Symbol('foo');
let b = Symbol('foo');
console.log(s === b); // false
Symbol.for
Symbol.for(key: string) 可以保证返回相同的 symbol 类型, 如果传入的参数 key 已在全局 symbol 仓库中, 那么返回那个仓库中对应 key 的 symbol, 否则创建一个新的 symbol
Symbol.keyFor
Symbol.keyFor(s: symbol) 接受一个 symbol 作为参数,返回参数 s:symbol 的 key, s: symbol 必须是通过 Symbol.for(key: string) 创建在全局 symbol 仓库中的才行,否则会返回 undefined
let s = Symbol.for('foo');
console.log(Symbol.keyFor(s)); // 'foo'
Symbol的使用场景
用作对象属性的键值(key), 可以有效防止对象属性的键值冲突