包装对象
# 一、基本类型可以调用方法吗?
我在学习 Unicode 字符集的时候进行了如下测试:
// 获取'好'的unicode码点
console.log('好'.charCodeAt()) //22909
// 将22909转换成16进制
console.log(22909 .toString(16)) //'597d'
1
2
3
4
5
2
3
4
5
提示
注意直接数值通过.
调用方法时,可以再调用方法前空格,以免被认为是数值的小数点。也可以采用下面的方法:
22909..toString(16) //'597d'
(22909).toString(16) //'597d'
1
2
2
数值可以采用 toString()方法,然而数字本身并没有这个方法啊!我们在试一下:
let a = 22909;
a.toString(16); //'597d'
console.log(a.__proto__); //Number {0, constructor: ƒ, toExponential: ƒ, toFixed: ƒ, toPrecision: ƒ, …}
1
2
3
4
5
2
3
4
5
果然成功了,但是有一个问题了:数值是 Number 类型,即基本类型,只有属性名和值,本身是不存在属性和方法的,为什么能够调用属性和方法呢?
const str = "123";
console.log(typeof str); // string
console.log(str.toString()); // 123
const num = 123;
console.log(typeof num); // number
console.log(num.toString()); // 123
const bool = true;
console.log(typeof bool); // boolean
console.log(bool.toString()); // true
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 二、包装对象
JS 的数值、布尔、字符串类型的变量,在一定条件下,也可以自动变为对象,这就是原始类型的包装对象。
包装对象其实是一种特殊的引用类型,其与引用类型的主要区别在于生命周期!!!
- 一般的引用类型在使用 new 创建实例时(typeof 判断则是 object),在执行流离开当前作用域之前一直保存在内存中;
- 包装类型的对象,只存在该行代码的执行瞬间,然后会被立即销毁。(也意味着在运行时不能为基本类型添加属性和方法)
# 三、包装对象后台执行流程
基本类型中的 String、Number、Boolean 在调用属性和方法时候,后台执行过程可以简化为以下三步:
- 创建一个对象类型的实例;(如字符串则创建一个String类型实例)
- 调用该实例对象上的特定方法;
- 销毁该实例。
以字符串为例:
const str = 'abc';
const strNew = str.substring(0, 2); //'ab'
typeof str //'string'
typeof strNew //'string'
1
2
3
4
5
2
3
4
5
当运行到str.substring(0,2)
时候其实偷偷执行了以下三步:
let strObj = new String(str);
const strNew = strObj.subString(0,2);
strObj = null;
1
2
3
2
3
# 四、扩展--包装类型注意事项
- 包装对象和相同的原始类型的值相等吗?
不相等。因为包装对象是引用类型,原始类型是基本类型。包装对象的最大目的就是可以让原始类型的值可以方便调用某些方法。
- 如何给基本类型添加属性和方法?
在基本包装对象的原型下面添加,每个对象都有原型。
let str = 'abc'; //定义一个基本类型,字符串
String.prototype.a = 1; //在基本包装类型String的原型上添加属性a
console.log(str.a); //1
console.log(str.__proto__) //String {'', a: 1, constructor: ƒ, anchor: ƒ, big: ƒ, …}
console.log(str.__proto__ === String.prototype) //true
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
- 同一个字符串调用两次相同的方法,其包装对象相等吗?
不相等。调用结束之后,包装对象实例就会自动销毁。所以下一次调用字符串的属性或方法时,实际上是调用一个新生成的对象,而不是上次调用时生成的那个对象。这也说明了为什么不能直接给字符串、数字、布尔值添加属性和方法。
编辑 (opens new window)
上次更新: 2022/06/16, 10:52:37