Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS 的拆箱与装箱 #5

Open
liangbus opened this issue Nov 17, 2019 · 1 comment
Open

JS 的拆箱与装箱 #5

liangbus opened this issue Nov 17, 2019 · 1 comment

Comments

@liangbus
Copy link
Owner

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

###装箱
我们都知道 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
Copy link

YuetTong commented Mar 3, 2022

在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
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants