一小段js引来的问题

var x = 1;
var obj = {
  valueOf: function() {
    x = 2;
    return 0;
  }
};
console.log(x); //1
console.log(obj.valueOf()); //0
console.log(obj); //Object
console.log(obj == 0,x); // true 2

1问:为什么都是输出x,两者值不同?
2问:obj出来的是个Object,为什么和0比较会true?
3问:接上问,出现true,是因为==的类型转换吗?那我把obj里的valueOf改成其它对象名,为什么就变成false了(如下)?

var x = 1;
var obj = {
  asd: function() {
    x = 2;
    return 0;
  }
};
console.log(x); //1
console.log(obj.asd()); //0
console.log(obj); //Object
console.log(obj == 0,x); // false 2
阅读 3.3k
4 个回答
  1. 执行valueOf的时候,里面的x = 2把外部的x值给改了。
  2. 类型不同做比较的过程中调用了valueOf,而你给当前对象添加了valueOf,就不会调用原型链上的valueOf了,所以拿到了0。这个可以搜下相等比较的相关问题。
  3. 同2。

相等比较的东西仅供参考,因为我记不清了,可能有错误。

var a = {}
a.valueOf = function () {console.log('valueOf');return 1}
a.toString = function () {console.log('toString')}
a == 1
// 可看到打印出了
// valueOf
// 如果将valueOf方法改为
a.valueOf = function () {console.log('valueOf');return a}
// 即返回一个非基本数据类型,会看到
// valueOf
// toString

也就是会先调用valueOf,如果拿到的不是基本数据类型(这一点不太确定)还会再调用toString
好像Date类型的数据调用的顺序也不一样,你再自己查查相等判断的规则吧。

js在做比较的时候会调用对象的valueOf函数,第一种写法相当于你把valueOf函数重写了,所以执行obj==0的时候实际上是执行的 0==0,返回true
第二种写法在比较的时候会直接调用原型链的valueOf,此时的asd函数是没用的,楼主可以试一下一个对象的valueOf返回的结果是什么。这个时候返回的是false
另外,楼主可以试一下第一种写法的valueOf最后改成return 1,再测试一下结果就明白了

其实很简单,第一个写法obj==0返回true就是因为js在比较的时候调用了valueOf函数,而你的obj里面有valueOf函数所以js直接执行的是obj本身的valueOf而非原型链上的valueOf,所以才返回的true。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏