为了账号安全,请及时绑定邮箱和手机立即绑定

toString与valueOf相关面试点

一问:每个对象都有toString和 valueOf,什么情况下先触发哪个?

toString() 返回一个表示该对象的字符串

当对象表示为文本值或以期望的字符串方式被引用时,toString方法被自动调用。

toString特殊情况

var obj = {}

console.log(obj.toString()) // [object object]

console.log(toString.call(new Date)) // [object Date]

console.log(toString.call(new String)) // [object String]

console.log(toString.call(Math)) // [object Math]

console.log(toString.call(window)) // [object Window]

console.log(toString.call(undefined)) // [object undefined]

console.log(toString.call(null)) // [object null]


其他类型的toString

var arr = [1,2,3,4]

console.log(arr.toString()) // "1,2,3,4"

var str = '1234'

console.log(str.toString()) // "1234"

var fn = function () { console.log('fn') }

console.log(fn.toString()) // "function () { console.log('fn') }"

可以自定义一个toString方法覆盖原来的方法

obj.toString = function () { return ‘a new toString’}

console.log(obj+’ hello’) // a new toString hello


valueOf() 表示指定对象的原始值(数值、字符串和布尔值)

返回对象本身

var obj = {}

obj.valueOf() // {}

var x = [1,2,3]

x.valueOf() // [1,2,3]

var y = function(){console.log('valueOf')}

y.valueOf() // function(){console.log('valueof')}

var z = 123

z.valueOf() // 123


可以自定义一个valueOf方法覆盖原本的,类同toString

valueOf比toString优先级更高

var object = {

    toString:function(){

        console.log('toString')

        return Object.prototype.toString.call(this)

    },

    valueOf:function(){

        console.log('valueOf')

        return Object.prototype.valueOf.call(this)

    }

}

alert(object) // 控制台:toString 弹出[object object] 控制台:valueOf

alert(+object) // NaN 控制台:toString

alert(object=={}) // false

alert(object==={}) // false

alert(object=='test') // 弹出false 控制台valueOf toString

alert(object==='test') // false

function fn () {

    return 20;

}

console.log(fn + 10)

返回结果:

function fn () {

    return 20;

}10

console.log(fn + 'hello');

返回结果:

function fn () {

    return 20;

}hello

fn.toString = function (){

    return 10;

}

console.log(fn + 10) // 20

console.log(fn + 'hello') //10hello

fn.valueOf = function () {

    return 5;

}

console.log(fn + 10) //15

console.log(fn + 'hello') //5hello


二问:toString与valueOf什么情况下先执行

如果没有重新定义valueOf和toString,其隐式转换会调用默认的toString()方法。如果重新定义了,那么其转换会按照定义的来。其中,valueOf比toString优先级更高。

var obj = {}

console.log(obj+10) // [object object]10

console.log(obj+'hello') // [object object]hello

var arr = [1,2,3,5]

console.log(arr+20) // 1,2,3,520

console.log(arr+'hello') // 1,2,3,5hello

var date = new Date(0)

console.log(date.toString()) //Thu Jan 01 1970 08:00:00 GMT+0800 (中国标准时间) 

console.log(date.valueOf()) //0

console.log(date+1) //Thu Jan 01 1970 08:00:00 GMT+0800 (中国标准时间)1


特殊情况:alert,[x].join(‘’)等这类特殊的表达,均调用toString(),须当特例记住

var x = {

  toString: function () {

    return 'foo'

  },

  valueOf: function () {

    return 42

  }

}

alert(x) //弹出foo

console.log('x='+x) //x=42

console.log(x+'=x') //42=x

console.log(x+'1') //421

console.log(x+1) //43

console.log(['x+', x].join('')) // x+foo


三问:

1.如何使if(v == 2 && v == 4 && v == 8)

const v = {

    value: 2,

    valueOf: function () {

        return Math.pow(2, v.value++)

    }

}

const equ = (v==2 && v==4 && v==8)

console.log(equ); //true


四问:

The question is : can (a==1 && a==2 && a=3) ever evaluate to true? The answer is Yes.

const a = {

    currentVal: 0,

    valueOf: function () {

        return this.currentVal += 1

    }

}

const equality = (a==1&&a==2&&a=3)

console.log(equality) // true

解析:隐式类型转换,在对象上执行类型转换时,JavaScript首先尝试调用该对象的valueOf()方法。

Object.prototype.valueOf() 每个对象都有valueOf方法,返回正在调用的对象。


const b = {num: 0}

console.log(b.valueOf()) //返回对象本身:{num: 0}

console.log(typeof b.valueOf()) // 使用typeof验证返回的对象:object

重新定义valueOf方法返回调用它的值


b.valueOf = function () {

return this.num;

}

console.log(b.valueOf); //0

console.log(typeof b.valueOf()) //number

console.log(b.num == b.valueOf()) //true

此时执行

b == 0 

// true


参考资料:https://github.com/tammyDing/valueOf-toString


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
Web前端工程师
手记
粉丝
20
获赞与收藏
156

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消