类型转换之引用类型转换

js中的任何类型在做隐式转换时只存在两种:值类型转值类型,引用类型转换值类型。下面针对引用类型转换为值类型。

当一个引用类型转换为值类型的时候首先会调用valueOf方法,如果此时已经转换为值类型则结束,否则继续调用toString()方法进行转换。下面看例子

 

( function(){
  _toString=Boolean.prototype.toString;
  _valueOf=Boolean.prototype.valueOf;
  Boolean.prototype.valueOf= function(){
    alert('do valueOf');
     return {};
  };
  Boolean.prototype.toString= function(){
    alert('do toString');
     return _toString.call( this);
  }
}());
var obj= new Boolean( true);
var v= false;
alert(obj+v); // truefalse

在上面的例子中,我们通过改写Boolean中的valueOf方法来使其返回一个引用类型对象,这样就迫使其必须再调用一次toString以使其返回值类型,默认的Boolean对象调用一次valueOf就已经转换为值类型(返回true而不是'true',这样参与最后的运算时输出1),所以根本不会再调用toString;最后返回'true'字符串,当’true'+false时false转换为'false'字符串

因此我们发现依次输出

do valueOf

do toString

truefalse

接下来我们再次场次修改Boolean的valueOf使其不返回对象,而是字符串'helllow javascript'

 

Boolean.prototype.valueOf= function(){
    alert('do valueOf');
     return {};
  };

 

,这样意味着执行valueOf后已经返回了值类型,就不需要再次调用toString方法了,因此结果输出

do Valueof

hellow javascript

不过这样还不满足,因为我们只是一味的改 valueOf,我们尝试改下toString试试,我们让其也返回一个对象,那一味着经过toString后还是没有转换为值类型

那已经违背了我们最终必须转换为值类型的定理,因此这样的改动会报错

  Boolean.prototype.toString= function(){
    alert('do toString');
     return {};
  }

 最后执行比较的时候提示”无法将obj转换为原始类型“

讲到这里最后再来一个例子

 

var arr = [];
alert(arr ==  false); // true

 上面为什么为true,我们来分析下

 1、发现arr为引用类型的对象,因此调用内部的valueOf,返回还是引用类型本身。

2、根据上面valueOf返回的不是值类型,因此再次执行toString,我们知道数组执行toString会展开其内部元素,然后拼接为字符串,

因此空元素的arr.toString()后返回 空的字符串''。

3、最后我们知道空的字符串会转换为false,因此arr==false会输出true了。

空说理论无凭,我们还是以实际代码来验证

( function(){
   _valueOf = Array.prototype.valueOf;
   _toString = Array.prototype.toString;
   Array.prototype.valueOf=  function(){
     alert('do valueOf');
      var arrValueOf = _valueOf.call( this); // 执行默认的valueOf
     alert( typeof arrValueOf); // 输出object
      return arrValueOf; // 记得返回该值不至于改变默认的结果,否则相当于重写valueOf后使返回了undefined吗,这样就是告诉引擎已经是值类型了,就不会再调用toString,你可以试试

   };
   Array.prototype.toString =  function(){
     alert('do toString');
      var arrToString = _toString.call( this); // 执行默认的toString;
     alert(arrToString); // 输出空字符串'';
      return arrToString; // 记得返回该值不至于改变默认的结果,否则相当于重写toString后使返回了undefined;

   }
}());
var arr = [];
alert(arr ==  false); // true

 一个很有趣的问题?

![] // false 这里的类型转换没有调用到valueOf等
[] == ![] // true

 

 

 

转载于:https://www.cnblogs.com/fuyun2000/archive/2012/03/22/2411062.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值