liangbus / blogging

Blog to go
10 stars 0 forks source link

JS 的拆箱与装箱 #5

Open liangbus opened 4 years ago

liangbus commented 4 years ago

装箱:把基本类型转换为对应的引用类型的操作

拆箱:与装箱相反,把引用类型转换为基本类型的操作

装箱

我们都知道 JS 有基本类型(值类型)和引用类型之分 我们可以看看基本类型赋值方式

const n = 101
const s = 'hey hey'

基本类型赋值完其变量就是一个值,但我们都知道,只有对象才拥有方法,而基本类型并非对象 其实这是 JS 在背后有做了一层处理,这个处理的过程,就叫装箱,它使得这些值也拥有了其对应基本类型的原型方法

三个步骤

  1. 创建该基本类型的实例
  2. 调用该实例上面特定的方法,属性
  3. 销毁该实例
const n = 101
const m = new Number(101)
console.log(typeof n) // "number"
console.log(typeof m) // "object"
console.log(n == m) // true, 两个等号会自动触发隐式转换 toValue, toString 方法
console.log(n === m) // false, 三个等号是严格比较,不会触发隐式转换,直接比较其值
console.log(n.constructor === m.constructor) // true, 构造函数是一样的
console.log(n.toString === m.toString) // true
n.laugh = function() { alert('I am laughing') } // 隐式装箱
m.laugh = function() { alert('You are laughing') } // 显式装箱
n.laugh() // Uncaught TypeError: a.laugh is not a function. JS 自己创建的实例会被销毁,所以无法定义属性或者方法在上面
m.laugh() // "You are laughing"  new 出来的对象会一直存在于内存里,直到主执行栈离开当前作用域

拆箱

拆箱的过程就正好相反,一般是通过对应基本类型的 toString 和 toValue 方法来实现

console.log(n === m.valueOf()) // true
const s = new String('101')
console.log(s.valueOf() === n) // false
YuetTong commented 2 years ago

在JavaScript里面有个引用类型叫做基本包装类型,它包括String、Number和Boolean。那么它和基本的类型String、Number和Boolean是啥关系呢?接着往下看👀 装箱操作 所谓的装箱,是指将基本数据类型转换为对应的引用类型的操作。而装箱又分为隐式装箱和显式装箱。 隐式装箱 对于隐式装箱,我们看下下面的代码: var s1 = 'call_me_R'; // 隐式装箱 var s2 = s1.substring(2); 复制代码上面代码的执行步骤其实是这样的:

创建String类型的一个实例; 在实例中调用制定的方法; 销毁这个实例。

上面的三个步骤转换为代码,如下:

1

var s1 = new String('call_me_R');

2

var s2 = s1.substring(2);

3

s1 = null; 复制代码隐式装箱当读取一个基本类型值时,后台会创建一个该基本类型所对应的基本包装类型对象。在这个基本类型的对象上调用方法,其实就是在这个基本类型对象上调用方法。这个基本类型的对象是临时的,它只存在于方法调用那一行代码执行的瞬间,执行方法后立即被销毁。这也是在基本类型上添加属性和方法会不识别或报错的原因了,如下: var s1 = 'call_me_R'; s1.job = 'frontend engineer'; s1.sayHello = function(){ console.log('hello kitty'); } console.log(s1.job); // undefined s1.sayHello(); // Uncaught TypeError: s1.sayHello is not a function 复制代码显示装箱 装箱的另一种方式是显示装箱,这个就比较好理解了,这是通过基本包装类型对象对基本类型进行显示装箱,如下: var name = new String('call_me_R'); 复制代码显示装箱的操纵可以对new出来的对象进行属性和方法的添加啦,因为通过通过new操作符创建的引用类型的实例,在执行流离开当前作用域之前一直保留在内存中。 var objStr = new String('call_me_R'); objStr.job = 'frontend engineer'; objStr.sayHi = function(){ console.log('hello kitty'); } console.log(objStr.job); // frontend engineer objStr.sayHi(); // hello kitty 复制代码拆箱操作 拆箱就和装箱相反了。拆箱是指把引用类型转换成基本的数据类型。通常通过引用类型的valueOf()和toString()方法来实现。 在下面的代码中,留意下valueOf()和toString()返回值的区别: var objNum = new Number(64); var objStr = new String('64'); console.log(typeof objNum); // object console.log(typeof objStr); // object

拆箱

console.log(typeof objNum.valueOf()); // number 基本的数字类型,想要的 console.log(typeof objNum.toString()); // string 基本的字符类型,不想要的 console.log(typeof objStr.valueOf()); // string 基本的数据类型,不想要的 console.log(typeof objStr.toString()); // string 基本的数据类型,想要的

作者:Jimmy 链接:https://juejin.cn/post/6844903859765133320 来源:稀土掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。