基本包装类型/类型转换(装箱/拆箱)

基本包装类型

js中有3个特殊的引用类型boolean numer string。

每当读取一个基本类型值的时候,后台会创建一个对应的基本包装类型对象,从而让我们能够调用一些方法来操作这些数据。

let s1 = "text";
let s2 = s1.sunstring(2);

s1是一个基本类型,当第二行代码访问s1时,进入读取模式,从内存中读取这个字符串的值,在读取模式中访问字符串时,后台会完成下列处理
1.创建String类型的一个实例
2.在实例上调用指定的方法
3.销毁这个实例

可以想象成以下代码

let s1 = new String("text");
let s2 = s1.substring(2);
s1 = null;

引用类型与基本包装类型的主要区别是对象的生存周期。使用new操作符创建的引用类型的实例,在执行流离开当前作用域之前都一直保存在内存中。而自动创建的基本包装类型的对象,只存在于一行代码的执行瞬间,然后立即销毁。

这意味着我们不能在运行的时候为基本类型值添加属性和方法。

let s1 = "text";
s1.color="red";
alert(s1.color);//undefined;

第二行创建的String对象在执行第三行的时候已经被销毁了。第三行创建了一个新的String对象,没有color。

装箱与拆箱

把基本数据类型转换为对应的引用类型的操作称为装箱,把引用类型转换为基本的数据类型称为拆箱。

上面介绍的“每当读取一个基本类型值的时候,后台会创建一个对应的基本包装类型对象”就是js的装箱。

将引用类型对象转换为对应的值类型对象,它是通过引用类型的valueOf()或者toString()方法来实现的。如果是自定义的对象,你也可以自定义它的valueOf()/tostring()方法,实现对这个对象的拆箱。

一般来说,对象到字符串的转换经过了如下步骤:

  1. 如果对象具有toString()方法,则调用这个方法。如果它返回一个原始值,js将这个值转换成字符串,并返还这个字符串结果。
  2. 如果对象没有toString()方法,或者这个方法并不返回一个原始值,那么js将调用valueOf()方法。
  3. 否则,js无法从toString()或者valueOf()获得一个原始值,因此这时它将抛出一个类型错误异常。

一般来说,对象到数字的转换过程中,js做了同样类似的事情,但这里它会首先尝试使用valueOf()方法:

  1. 如果对象具有valueOf()方法,后者返回一个原始值,则js将这个原始值转换成数字,并返回这个数字。
  2. 否则,如果对象具有toString()方法,后者返回一个原始值,则js将转换并返回。(首先js转换成相应的字符串原始值,再继续将这个原始值转换成相应的数字类型,再返回数字)
  3. 否则,js抛出一个类型错误异常。

对象通过toString或valueOf方法转换为原始值,JS语言核心的内置类首先尝试使用valueOf(),再尝试使用toString()

==涉及的类型转换

在比较之前,==的两个操作符都会进行强制类型转换
在转换不同的数据类型时,==!= 操作符遵循系列基本的原则

  1. 如果有一个操作数时布尔值,则在比较相等性之前先将其转换为数值,即是调用Number()函数
  2. 如果一个操作数是字符串,另一个数时数值,在比较相等性之前先将字符串转换为数值;同理底层是Number()函数
  3. 如果一个操作数是对象,另一个操作数不是,则调用对象的

valueOf()方法,用得到的基本类型按照前面的规则进行比较
以上是类型转换时遵循的原则,在转换成基本数据类型以后,会出现两边都是同个类型和不同类型的情况,在进行比较时又遵循以下的原则

  1. null 和 undefied 是相等的,这是js的规定,但是其实在底层,undedined的值是派生自null的,所以逻辑等时要返回true
  2. 如果有一个操作数时NaN,则返回false(NaN不与任何操作符逻辑等或全等,包括NaN)
  3. 如果两个操作符都是对象,则比较它们是不是同一个对象,则返回true,否则返回false

例子

console.log(undefined==false)
console.log(null==false)
console.log(null==0)
console.log(undefined==0)
//以上都输出false

undefined == false
//根据转换规则1,调用Number()方法将其转换为数值类型
//根据上面结果,则转换为 NaN == 0 
//根据比较规则2,NaN不与任何操作符逻辑等,则返回false

null == false
Number(null) == Number(false) => 0  == 0  => true  //这是不行的
//可在控制台输出的是false啊?这只能说是js的特殊情况了,
//就像null == undefined一样,同样存在下列的特殊情况
null == 0  //false
null == false //false
true == 2 //false 因为Number(true)返回的是1

console.log(null==undefined)//true
console.log(null===undefined)//false

console.log(2==true)//false
//规则1 Number(true)=>1
//2==1 =>false

valueOf() toString()

var bbb = { 
i: 10, 
toString: function() { 
console.log('toString'); 
return this.i; 
}, 
valueOf: function() { 
console.log('valueOf'); 
return this.i+10; 
} 
} 
alert(bbb);// 10 toString 
alert(+bbb); // 20 valueOf 
alert(''+bbb); // 20 valueOf 
alert(bbb>15);//true 
alert(String(bbb)); // 10 toString 
alert(Number(bbb)); // 20 valueOf 
alert(bbb == '20'); // true valueOf 

使用运算符的alert(+bbb);alert(’’+bbb);alert(bbb>15);都是调用的valueOf

如果只重写了toString,对象转换时会无视valueOf的存在来进行转换。
如果只重写了valueOf,对象转换时原本使用toString的会使用Object.prototype上的toString。

var aa = { 
i: 10, 
toString: function() { 
console.log('toString'); 
return this.i; 
} 
} 
alert(aa);// 10 toString 
alert(+aa); // 10 toString 
alert(''+aa); // 10 toString 
alert(String(aa)); // 10 toString 
alert(Number(aa)); // 10 toString 
alert(aa == '10'); // true toString 


//再看valueOf。 
var bb = { 
i: 10, 
valueOf: function() { 
console.log('valueOf'); 
return this.i; 
} 
} 
alert(bb);// [object Object] 
alert(+bb); // 10 valueOf 
alert(''+bb); // 10 valueOf 
alert(String(bb)); // [object Object] 
alert(Number(bb)); // 10 valueOf 
alert(bb == '10'); // true valueOf 
//发现有点不同吧?!它没有像上面toString那样统一规整。
//对于那个[object Object],我估计是从Object那里继承过来的,我们再去掉它看看。 


Object.prototype.toString = null; 
var cc = { 
i: 10, 
valueOf: function() { 
console.log('valueOf'); 
return this.i; 
} 
} 
alert(cc);// 10 valueOf 
alert(+cc); // 10 valueOf 
alert(''+cc); // 10 valueOf 
alert(String(cc)); // 10 valueOf 
alert(Number(cc)); // 10 valueOf 
alert(cc == '10'); // true valueOf 

参考文章:
https://www.cnblogs.com/imwtr/p/4392041.html
《js高级程序设计》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Java中,基本类型包装类之间可以进行自动装箱箱的操作,即将基本类型转换成对应的包装类,或将包装转换成对应的基本类型。下面是基本类型和对应的包装类: | 基本类型 | 包装类 | | -------- | ------ | | byte | Byte | | short | Short | | int | Integer| | long | Long | | float | Float | | double | Double | | char | Character | | boolean | Boolean | 基本类型包装类的转换可以通过以下方式进行: 1. 基本类型转换包装类: ```java int i = 10; Integer integer = Integer.valueOf(i); // 自动装箱:int -> Integer long l = 100L; Long aLong = Long.valueOf(l); // 自动装箱:long -> Long double d = 3.14; Double aDouble = Double.valueOf(d); // 自动装箱:double -> Double ``` 2. 包装转换基本类型: ```java Integer integer = Integer.valueOf(10); int i = integer.intValue(); // 自动箱:Integer -> int Long aLong = Long.valueOf(100L); long l = aLong.longValue(); // 自动箱:Long -> long Double aDouble = Double.valueOf(3.14); double d = aDouble.doubleValue(); // 自动箱:Double -> double ``` 除了自动装箱和自动箱,还可以使用包装类的静态方法 parseXXX() 将字符串转换基本类型包装类。其中,XXX 表示对应的基本类型名字,例如 Integer 类型的 parseXXX() 方法为 parseInt()。 ```java String str = "123"; int i = Integer.parseInt(str); // 将字符串转换成 int 类型 String str2 = "3.14"; double d = Double.parseDouble(str2); // 将字符串转换成 double 类型 String str3 = "true"; boolean b = Boolean.parseBoolean(str3); // 将字符串转换成 boolean 类型 ``` 同样,也可以使用包装类的 toString() 方法将基本类型包装转换成字符串。 ```java int i = 123; String str = Integer.toString(i); // 将 int 类型转换成字符串 double d = 3.14; String str2 = Double.toString(d); // 将 double 类型转换成字符串 Boolean b = true; String str3 = Boolean.toString(b); // 将 boolean 类型转换成字符串 ``` 对于字符串和基本类型包装类之间的转换,可以使用包装类的 valueOf() 方法或相应的 parseXXX() 方法。 ```java String str = "123"; int i = Integer.valueOf(str); // 将字符串转换成 int 类型 String str2 = "3.14"; double d = Double.parseDouble(str2); // 将字符串转换成 double 类型 String str3 = "true"; boolean b = Boolean.valueOf(str3); // 将字符串转换成 boolean 类型 int i = 123; String str4 = String.valueOf(i); // 将 int 类型转换成字符串 double d = 3.14; String str5 = String.valueOf(d); // 将 double 类型转换成字符串 Boolean b = true; String str6 = String.valueOf(b); // 将 boolean 类型转换成字符串 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值