JS类型转换
JavaScript是一种动态类型弱类型的语言,我们在声明变量的同时不需要显式地指出它的类型,变量的类型将在运行时自动确定,而且可以随时更改一个变量的类型:
let temp = 1; // number
temp = '123'; // string
temp = {}; // object
同时js支持各种类型之间的隐式转换,将一个字符串除以2在js中也是合法的操作:
let str = '100'; // string
str /= 2; // number
console.log(str); // 输出50,'100'被隐式转换成了整数
而事实上,js中的大部分类型转换都比较简单,具体转换规则表在网上可以很容易找到。比较复杂的是装箱和拆箱操作,下面是我的一些学习体会和总结。
装箱转换(Boxing)以及拆箱转换(Unboxing)
JavaScript中共有六种原始数据(primitive data)类型,其中的number、string、boolean和ES6中新增的symbol类型,都有一个基本包装类型/对象(Wrappers)与之对应。
装箱转换指的就是将原始数据类型转换为对应的对象;拆箱转换与之对应,指的是将包装对象转换为对于的原始数据类型。
装箱转换
1.显式装箱(Explict boxing)
很好理解,手动完成原始数据类型到包装类型的转换:
let temp = 1;
typeof temp // number
temp = new Number(1); // 原始数据类型 => 包装类型
typeof temp // object
// Symbol()函数无法通过new调用,我们可以使用Object()函数来显式装箱
let symbolObject = Object(Symbol('abc'));
typeof symbolObject // object
但是需要注意的是,使用手动装箱可能会导致一些语义上的错误:
let temp = new Boolean(true);
if(temp) console.log("true") // true
temp = new Boolean(false); // 此时temp为object,转换为布尔值时为true
if(!temp) console.log("false");
else console.log("true"); // true
2.隐式装箱(Implict boxing)
在JavaScript中,只有对象才有方法。所以当我们在基本类型上使用方法时,js实际上会创建一个临时对象来调用这个方法,这个临时对象将会在语句执行完毕后被销毁。
let s1 = "1234";
let s2 = s1.substring(1); // s2 === 234
// 对上述第二行代码实际执行过程的理解
let temp = new String(s1);
let s2 = temp.substring();
temp = null
// 证明第二行代码确实创建了临时变量
String.prototype.proof = () => {
console.log("proof函数被调用!");
}
'123'.proof(); // proof函数被调用!
拆箱转换
拆箱转换即装箱转换的逆过程,同样可以分为显式拆箱和隐式拆箱。
1.显式拆箱(Explicit unboxing)
let temp = (new Number(1)).valueOf(); // 包装类型 => 原始数据类型
typeof temp; // number
2.隐式拆箱(Implicit unboxing)
let temp = new Number(1);
temp == 1; // true
参考篇目
- 通俗的方式理解动态类型,静态类型;强类型,弱类型
- JavaScript类型:关于类型,有哪些你不知道的细节?
- Boxing and unboxing in JavaScript.
- 面试题:在javascript中,1与Number(1)有什么区别(第一条评论——eyesofkids)
- JavaScript Boxing Wrappers.