JavaScript 中的数据类型分为原始类型和对象类型。
基本类型的字符串和数字不是对象,但可以通过称为包装对象的机制将它们视为对象。
这一次,我将介绍原始类型和包装对象。
原始类型
在JavaScript中有7种原始类型
数字(Number)
字符串(String)
长整数(BigInt)
布尔值(Boolean)
null
undefined
符号(Symbol)
以下代码定义字符串。
let str = 'string';
尝试对str使用toUpperCase方法。
let str = 'string'; console.log(str.toUpperCase()); // "STRING"
这将以大写形式输出“STRING”。
但是,为什么原始类型的字符串str可以调用toUpperCase方法呢?
那是因为创建了与原始类型的值相对应的特殊对象。
让我们仔细看看。
包装对象
在原始类型中,除了null和undefined之外,都有一个对应的包装对象。
原始类型 | 包装对象 |
---|---|
数字 | Number |
字符串 | String |
长整数 | BigInt |
布尔值 | Boolean |
符号 | Symbol |
可以使用new运算符创建每个包装对象的实例。
例如,要创建字符串对应的String对象实例,可以这样写。
// 创建String对象的实例 let str = new String('string'); // 调用String对象的方法 console.log(str.toUpperCase()); // "STRING"
String可以将该对象'string'与包含的字符串值进行比较。
因此,这样的对象被称为原始类型值的包装对象。
声明变量时,原始类型的值仍然是该值的类型。
但是当你创建一个包装对象时,它的类型是对象。
let str = 'string'; console.log(typeof str); // "string" let wrapperStr = new String('string'); console.log(typeof wrapperStr); // "object" let num = 5; console.log(typeof num); // "number" let wrapperNum = new Number(5); console.log(typeof wrapperNum); // "object"
像这样,对象的类型发生了变化,就能使用相应的方法。
包装器对象的自动转换
通过使用new运算符创建包装对象,您可以调用该对象的方法。
下面的代码没有创建实例,但可以调用String对象的实例方法toUpperCase()。
let str = 'string'; console.log(str.toUpperCase()); // "STRING"
这是因为当您访问原始类型值的属性时,它会自动转换为包装对象。
这与使用new String()创建包装器对象的效果相同。
// 1和2相同 // 1.对字符串型的值进行方法的调用 let str = 'string'; str.toUpperCase(); // 2.创建包装对象后进行方法的调用 let wrapperStr = new String('string'); wrapperStr.toUpperCase();
一般来说,对于原始类型的数据使用字面值更好。
// 建议:使用字面值 let str = 'string'; let num = 5; // 不建议:使用包装对象 let wrapperStr = new String('string'); let wrapperNum = new Number(5);
原因是仅在必要时对原始值使用方法自动将它们转换为包装器对象。没有必要一开始就创建包装对象。
此外,使用字面值的原始类型值和使用包装对象的值可能会引起混淆,因为它们表示不同的类型。(例如:使用typeof运算符时,字符串类型为‘string’,包装对象为‘object’)
正因为如此,对于原始类型的数据,大多数情况下都使用字面值。
结语
这一次,我介绍了原始类型和包装对象。
除了null和undefined之外,每个原始类型的值都有各自对应的包装对象
new 运算符可用于实例化包装对象
访问原始类型值的属性时会自动将其转换为包装对象
从而可以在每个包装对象上调用方法