说明

  • toString()
  • valueOf()

这两个方法几乎出现在js中所有类型对应的内置对象的原型上(null和undefined除外),它们的出现解决了值运算的问题,但也出现了隐式转换这个让人头疼的问题。

toString()

返回一个表示当前值的特殊字符串,当对象表示为文本或以期望字符串被调用时,toString()方法会自动调用,比如用console.log()或者alert()方法输出值时,就会自动调用该方法,在进行值比较时,也可能触发该方法,也有可能触发valueOf方法,关于何时触发这两个方法,下文会进行介绍。

<script>
       <script>
        var str = "1";
        var num = 1;
        var boolean = true;
        var obj = {};
        var func = function() {}
        console.log(str.toString()); //1
        console.log(num.toString()); //1
        console.log(boolean.toString()); //true
        console.log(obj.toString()); //["object Object"]
        console.log(func.toString()); //function(){}
    </script>

js中许多的类型对象上都重写了Object原型上的toString方法,我们还发现,当对象调用toString()时,它会返回一个表示当前值类型的字符串,它直接调用了Object原型上的toString。

比较对象
typeof 可以用来判断基本类型变量的类型(null除外,null会返回object,这是js历史遗留问题),当我们用typeof来比较对象时,发现并行不通,因为它都会返回一个object,比如当我们运用深拷贝copy对象时,就不能准确地判断出数组和对象,并做出相应的处理,因为它们都会返回一个object。
object原型上的toString方法,可以返回一个表示值类型的一个字符串,那么我们就可以使用object原型上的toString方法来判断对象。

  <script>
        var toString = Object.prototype.toString

        toString.call(1) // '[object Number]'
        toString.call('1') // '[object String]'
        toString.call(false) // '[object Boolean]'
        toString.call(() => {}) // '[object Function]'
        toString.call([]) // '[object Array]'
        toString.call({}) // '[object Object]'
        toString.call(null) // '[object Null]'
        toString.call(undefined) // '[object Undefined]'
        toString.call(new Date()) // '[object Date]'
        toString.call(window) // '[object Window]'
        toString.call(Math) // '[object Math]'
    </script>

运算操作时带来的隐式转换问题

var c = [1, 2, 3]
var d = {a:2}
console.log(2 + 1)  // 3
console.log('s')    // 's'
console.log('s' + 2)  // 's2'
console.log(c < 2)  // false        (一次 => 'Array')
console.log(c + c)  // "1,2,31,2,3" (两次 => 'Array')
console.log(d > d)  // false        (两次 => 'Object')

数组原型上重写了toString方法,它会把数组用join(“,”)方法分割,输出字符串。
toString()重写

    <script>
        String.prototype.toString = function() {
            var num = 1;
            return `myString${num}`;
        }
        var str = "2"
        console.log(str.toString()); //myString1
    </script>

valueOf()

返回当前包装对象的原始值。
这个 API 通常是由 JavaScript 引擎内部调用,开发者一般情况下不会使用,其功能和 toString 大同小异。
二者区别
共同点:两者都是在值运算的时候会自动调用,从而触发隐式转换
不同点:默认返回值不同,并且存在调用优先级关系
在二者并存的情况下,数值运算时优先使用 valueOf ,字符运算时优先使用 toString 。

class A {
  construtor(num) {
  this.num = num
  }
  
  valueOf() {
    return this.num
  }
  
  toString() {
    return `我好有钱:${this.num}`
  }
}

const a = new A(100)

console.log(String(a)) // '我好有钱:100'             -> toString
console.log(Number(a)) // 100                       -> valueOf
console.log(a + '22') // '10022'          -> valueOf
console.log(a == 100) // true            -> valueOf
console.log(a === 100) // false,全等不触发隐式转换

总结
总结可以发现,valueOf 更加偏向于运算,toString 更加偏向于调用。
在进行对象运算时,将优先调用 toString 方法,如若没有重写 toString 方法,则会调用 valueOf 方法;如果两个方法都没有重写,则会调用 Object 上面的 toString
当进行强制类型转换时,如果转换成字符串则会调用 toString ,转换成数字则会调用 valueOf
使用运算符进行运算时,valueOf 的优先级高于 toString。
原文链接

原文地址:http://www.cnblogs.com/zx529/p/16819510.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性