felix-cao / Blog

A little progress a day makes you a big success!
29 stars 4 forks source link

JavaScript Boxing & Unboxing #211

Open felix-cao opened 2 years ago

felix-cao commented 2 years ago

一、类型转换

JavaScript 是一种动态类型编程语言,对变量数据类型是宽容的,不需要显式的指出它的数据类型,变量的数据类型会在程序运行时自动确定,而且可以随时更改一个变量的数据类型, 这在静态类型编程语言是不可能的。

let v = "123"; // string
v = 123; // number
v = {}; // object

上面的代码变量 v 可以在光天化日下毫无忌惮的进行 string, number, object等各种数据类型之间进行转换。

同时JavaScript 还支持各种类型之间的隐式转换

let v = '100'; // string
v /= 2; // number
console.log(v);

上面的代码把字符串 100赋值给变量 v, 再对其进行 /= 运算赋值操作,v 会被隐式转换(Implicit Coercion)为 number 型。

二、Boxing and Unboxing

JavaScript 的 Boxing 和 Unboxing 也是一种类型转换。

JavaScript中共有六种 Primitive values, 其中 string, number, boolean, symbol, 都有一个包装对象(Wrapper)与之对应。

Boxing 就是指将 Primitive 类型的数据转换为对应的对象;

Unboxing 与之相反,即将包装对象转换为对应的`Primitive类型的数据

2.1、Manual Boxing

手动 Boxing, 即手动完成 Primitive values 到 包装类型的转换,这是一种显式转换

let v = 1;
typeof v; // number
v = new Number(1); // Primitive to Object
typeof v; // object

2.2、Auto-Boxing

let v = "100";
let v2 = v.length;

上面代码给 v 赋值一个字符串100, 再访问vlength, 然后赋值给 v2;

然而v是一个Primitive value, 在 JavaScript 中只有对象才有属性和方法 , 为什么 vlength 属性呢?

当访问基本类型的属性或方法时,JavaScript首先将其隐式转换为包装器对象,再访问其上的属性和方法。访问完包装器对象上的属性和方法后,将其丢弃。这就是 Auto-Boxing, 上面的代码可以理解为:

let temp = new String("100");
let v2 = temp.length;
temp = undefined

Reference