美文网首页
对象toString和valueOf方法的详解

对象toString和valueOf方法的详解

作者: vinterx | 来源:发表于2019-04-13 02:24 被阅读0次

    讲解这章之前,先看个简单的案例

    let qq = 'vinter'
    let aa = 13
    let bb = true
    let obj = {name: 'vinter'}
    let arr = [1,2]
    //      常用对象
    let date = new Date()
    let fn = () => {}
    // console.dir(Number)
    // console.dir(String)
    // console.dir(Boolean)
    // let cc = null
    // let dd = undefined
    console.log(qq.toString())
    console.log(aa.toString())
    console.log(bb.toString())
    console.log(obj.toString())
    console.log(arr.toString())
    console.log(date.toString())
    console.log(fn.toString())
    console.log('==============')
    console.log(qq.valueOf())
    console.log(aa.valueOf())
    console.log(bb.valueOf())
    console.log(obj.valueOf())
    console.log(arr.valueOf())
    console.log(date.valueOf())
    console.log(fn.valueOf())
    
    image.png
    • 从上面可以看出,所有的常规数据类型的原型中都是具有toString()和valueOf方法的,所以实例才能调用这些方法,但
      \color{red}{null和undefined}是没有这两种方法的,NaN虽然是Number类型中的异类,但是也有这两种方法。
    • 20.toString()会被误解不是对象,是因为JS会首先解析其为浮点,(20).toString()能正常输出,所以数字也是对象。
    • 其次除了对象Object或者对象实例的toString方法会返回形如[object 类型]外,其他如String、Function、Number、Boolean等类型会调用自己的toString()方法返回原始值的字符串类型;而valueOf()方法则返回原始值。

    理解那些类型具有这两种方法后,接下来进入正题。
    上章节提到三个问题:

    • 对象Object的toString()和数组toString()方法的区别;
    • 对象toString()方法可以检查对象类型,可以归类有几种检查类型的方法;
    • toString()方法和valueOf()方法是如何被隐式调用的,在什么场景下会被隐式调用。

    四种类型检查比较

    写几种常用类型

    let str = '123456'
    let bol = true
    let num = 123
    let obj = {name: 'vinter'}
    let arr = [1,2,3]
    let nul = null
    let undef = undefined
    
    class Parent {
        constructor(age, sex) {
            this.age = age
            this.sex = sex
        }
    
        action() {}
    }
    
    class Son extends Parent {
        constructor(age,sex,name) {
            super(age,sex)
            this.name = name
        }
    
        say() {}
    }
    
    let son = new Son(18, 'male', 'vinter')
    

    注意:
    \color{red}{es6的箭头函数是不能创建构造函数的}

    let Son = () => {} //  这是错误的
    let Son = function(){} //  这是正确的
    let son = new Son()
    

    1、typeof
    示例

    console.log(typeof str)     //      string
    console.log(typeof bol)     //      boolean
    console.log(typeof num)     //      number
    console.log(typeof obj)     //      object
    console.log(typeof arr)     //      object
    console.log(typeof nul)     //      object
    console.log(typeof undef)       //      undefined
    console.log(typeof son)     //      object
    console.log(typeof Son)     //      function
    

    总结

    1. typeof检查的类型全都是小写字符串如"object"
    2. typeof能检查function
    3. typeof不能区分对象的类型,检测的对象除了函数外,全部输入“object”
    4. typeof检查null为对象而检查undefined为undefined

    2、instanceof

    console.log( str instanceof Object)     //      false
    console.log( bol instanceof Boolean)        //       false
    console.log( num instanceof Number)     //      false
    console.log( obj instanceof Object)     //      true
    console.log( arr instanceof Object)     //      true
    console.log( nul instanceof Object)     //      false
    console.log( undef instanceof Object)       //      false
    
    console.log( son instanceof Object)     //      true
    console.log( son instanceof Son)        //      true    重点
    console.log( Son instanceof Function)       //      true    重点
    console.log( Son instanceof Object)     //      true
    

    总结

    1. instanceof不能检查简单类型,只能检查复杂类型即对象
    2. instanceof能区分对象类型
    3. instanceof检测undefined和null不是对象

    3、Object.prototype.toString

    console.log( Object.prototype.toString.call(str))       //      [object String]
    console.log( Object.prototype.toString.call(bol))       //      [object Boolean]
    console.log( Object.prototype.toString.call(num))       //      [object Number]
    console.log( Object.prototype.toString.call(obj))       //      [object Object]
    console.log( Object.prototype.toString.call(arr))       //      [object Array]
    console.log( Object.prototype.toString.call(nul))       //      [object Null]
    console.log( Object.prototype.toString.call(undef))     //      [object Undefined]
    
    console.log( Object.prototype.toString.call(son))       //      [object Object]
    console.log( Object.prototype.toString.call(Son))       //      [object Function]
    

    转换

    console.log(Object.prototype.toString.call(str).slice(8, -1))   // [object String]  ==> String
    

    总结

    1. 这个方法是既能检查对象类型又能检测简单类型,并且还能检测null和undefined类型\color{red}{全能}
    2. 检测的类型都是首字母大写如:String,和typeof不同的地方(注意)
    3. 通常需要调用slice(8,-1)方法进行转换

    4、constructor

    console.log( str.constructor === String)        //      true
    console.log( bol.constructor === Boolean)       //       ture
    console.log( num.constructor === Number)        //      true
    console.log( obj.constructor === Object)        //      true
    console.log( arr.constructor === Object)        //      false
    console.log( arr.constructor === Array)     //      true 重点
    // console.log( nul.constructor === Object)     //      报错
    // console.log( undef.constructor === Object)       //      报错
    
    console.log( son.constructor === Object)        //      false
    console.log( son.constructor === Son)           //      true    重点
    console.log( Son.constructor === Object)        //      false
    console.log( Son.constructor === Function)      //      true    重点
    
    

    总结

    1. 不能检查null和undefined
    2. 能够区分对象类型
    3. 能够检测简单类型

    综合上述:
    简单的用typeof足够,但是对于要求严格的代码,推荐使用Object.prototype.toString.call(params).slice(8, -1)

    toString()方法和valueOf()方法是如何被隐式调用的

    注意:万物皆对象,null和undefined除外,这对下面理解有帮助。
    对象toString()和valueOf谁先被调用

    let obj = {
        valueOf: function(){
            console.log("valueOf")
            return 10;
        },
        toString: function(){
            console.log("toString")
            return '10';
        }
    }
    
    alert(obj)  //  toString     显示
    alert(++obj)  //  valueOf  运算
    
    console.log(obj == "10")  //  10 true   左右对象均调用valueOf()方法
    console.log(obj + "10") //   10  "1010"   (js的特殊例子,虽然都调用valueOf(),但是却转化为字符串)
    

    总结
    1、 在进行强转字符串类型时将优先调用toString方法,强转为数字时优先调用valueOf。
    2、 在有运算操作符的情况下,valueOf的优先级高于toString。
    3、valueOf偏于运算,而toString则偏向显示
    4、加法是个特殊的案例,虽然调用了valueOf方法但是却是字符串相加

    null、undefined、""、0、NaN

    //  比较运算符 ==    推荐使用比较运算符 ===
    console.log(1 == true)
    console.log(0 == false)
    console.log("0" == false)
    console.log([] == false)
    console.log("" == false)
    console.log(null == undefined)
    
    //  逻辑运算符&& || !(重要)
    console.log(!"")
    console.log(!0)
    console.log(!null)
    console.log(!undefined)
    console.log(!NaN)
    
    //  以上全部返回true
    

    相关文章

      网友评论

          本文标题:对象toString和valueOf方法的详解

          本文链接:https://www.haomeiwen.com/subject/prqgiqtx.html