对象toString和valueOf方法的详解

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

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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,128评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,316评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,737评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,283评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,384评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,458评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,467评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,251评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,688评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,980评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,155评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,818评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,492评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,142评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,382评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,020评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,044评论 2 352

推荐阅读更多精彩内容