JavaScript 對象的toString()和valueOf()

在進行數(shù)據(jù)轉(zhuǎn)化時,所有對象繼承了兩個轉(zhuǎn)換方法:
toString():返回一個反映這個對象的字符串窍育;
valueOf():返回它相應(yīng)的原始值溶褪。

1、toString()

當(dāng)對象表示為文本值時或期望以字符串的方式引用對象時丹锹,該方法被自動調(diào)用。對象obj在調(diào)用toString() 返回形如:[object type]芬失。其中type是對象類型楣黍。如果obj不是對象,toString() 返回obj應(yīng)有的文本值(不是單純的加”“)棱烂。

        let obj ={};
        console.log(obj.toString());//[object Object]
        console.log(obj.toString.call(new String));//[object String]
        console.log(obj.toString.call(new Date));//[object Date]
        console.log(obj.toString.call(new Array));//[object Array]
        console.log(obj.toString.call(new Number));//[object Number]
        console.log(obj.toString.call(Function));//[object Function]
        console.log(obj.toString.call(Math));//[object Math]
        console.log(obj.toString.call(undefined));//[object Undefined]
        console.log(obj.toString.call(null));//[object Null]
-----------------------------------------------------------------------------
        let objArr = [1, 2, 3, 4, 5];
        console.log(objArr.toString());//1,2,3,4,5
        let arr =[{id:123,name:'ShangSan'},'2',3,true];
        console.log(arr.toString());//[object Object],2,3,,true
        let objNum = 12345;
        console.log(objNum.toString());//12345
        let objBoolean=true;
        console.log(objBoolean.toString());//true
        let objFunc = function () {
            console.log('param');
        }
        console.log(objFunc.toString());
        // function () {
        //     console.log('param');
        // }

也可以復(fù)寫這個方法(自定義這個方法租漂,這個方法沒有參數(shù)且必須有個返回值)。

        let obj = {
            toString:function(){
                return '我是toString方法';
            }
        };
       console.log(obj.toString());//我是toString方法
       console.log(obj.toString.call(new String));//我是toString方法
不同類型對象的toString()方法的返回值
對象 返回值
Array 返回數(shù)組字符串颊糜,字符串以逗號隔開,如:"1,2,3,4"哩治,空數(shù)組為空字符串
Boolean 布爾字符串,"false""true"
Date 現(xiàn)在時間字符串衬鱼,如:"Thu Jul 25 2019 14:35:20 GMT+0800 (中國標(biāo)準時間)"
Function 函數(shù)本身字符串
Number 數(shù)字字符串
Object "[object Object]"
String 字符串值

2业筏、valueOf()

JavaScript 調(diào)用 valueOf() 方法用來把對象轉(zhuǎn)換成原始類型的值(數(shù)值、字符串和布爾值) 鸟赫。默認情況下, valueOf() 會被每個對象Object繼承蒜胖。每一個內(nèi)置對象都會覆蓋這個方法為了返回一個合理的值,如果對象沒有原始值抛蚤,valueOf() 就會返回對象自身台谢。

不同類型對象的valueOf()方法的返回值
對象 返回值
Array 返回數(shù)組對象本身
Boolean 布爾值
Date 存儲的時間是從 1970 年 1 月 1 日午夜開始計的毫秒數(shù) UTC
Function 函數(shù)本身
Number 數(shù)字值
Object 對象本身,這是默認情況
String 字符串值
 //let objArr = [1, 2, 3, 4, 5];
        let objArr = ['a', 'b', 'c', 'd', 'f'];
        console.log(objArr.valueOf());//["a", "b", "c", "d", "f"]
        let objBoolean = true;
        console.log(objBoolean.valueOf());//true
        let objDate = new Date();
        console.log(objDate.valueOf());//1555381853497
        let objFunc = function () {
            console.log('param');
        }
        console.log(objFunc.valueOf());
        // ? () {
        //     console.log('param');
        // }
        let objNum = 12345;
        console.log(objNum.valueOf());//12345
        let obj = {
            id: '1001',
            age: 19
        };
        console.log(obj.valueOf());//{id: "1001", age: 19}
        let objStr = new String('abcdfe');
        console.log(objStr.valueOf());//abcdfe

也可以復(fù)寫這個方法(自定義這個方法岁经,這個方法沒有參數(shù)且必須有個返回值)朋沮。

        let obj = {
            valueOf:function(){
                return '我是valueOf方法';
            }
        };
        console.log(obj.valueOf());//我是valueOf方法
        console.log(obj.valueOf.call(new String));//我是valueOf方法

那么問題來了,對象何時調(diào)用 toString(),何時調(diào)用 valueOf()缀壤?樊拓??

3诉位、優(yōu)先級

我們下面通過實例還說明骑脱,先定義一個基礎(chǔ)的對象obj,復(fù)寫toString()和valueOf()方法苍糠。

        let obj = {
            toString: function () {
                console.log('調(diào)用了 obj.toString');
                return {};
            },
            valueOf: function () {
                console.log('調(diào)用了 obj.valueOf')
                return 123;
            }
        }
3.1 直接輸出對象

直接 alert(obj)叁丧,輸出:調(diào)用了 obj.toString ;調(diào)用了 obj.valueOf。
修改toString返回值為基礎(chǔ)數(shù)據(jù)類型拥娄,valueOf返回值保持不變蚊锹。

        obj.toString = function () {
            console.log('調(diào)用了 obj.toString');
            return 'aaa'
        };

alert(obj),輸出:調(diào)用了 obj.toString 稚瘾。并沒有調(diào)用valueOf()牡昆。
得出結(jié)論:
直接輸出對象時,先調(diào)用其toString方法摊欠,若toString返回原始值就直接返回丢烘,否則繼續(xù)調(diào)用valueOf方法,若valueOf返回不是原始類型些椒,報錯播瞳。
注意:由于這種場景先調(diào)用toString,在調(diào)用valueOf免糕,若調(diào)用valueOf返回值為對象赢乓,會報錯。(所以就不舉例說明toString和valueOf返回都為對象的情況了)

3.2 對象參與運算

直接 alert(obj+‘1’)/ alert(obj+1)/alert(obj+true);石窑,輸出:只調(diào)用了 obj.valueOf牌芋。
直接 alert(obj==‘1’),輸出:只調(diào)用了 obj.valueOf松逊。
修改valueOf返回值為對象躺屁,toString返回值保持不變。

     obj.valueOf = function () {
            console.log('調(diào)用了 obj.valueOf');
            return [];
        }

alert(obj+1)棺棵,輸出:調(diào)用了 obj.valueOf楼咳。調(diào)用了 obj.toString 熄捍。并且報錯Uncaught TypeError: Cannot convert object to primitive value烛恤。
修改valueOf返回值為對象,再修改toString返回值為基礎(chǔ)數(shù)據(jù)類型余耽。

       obj.toString = function () {
            console.log('調(diào)用了 obj.toString');
            return 'aaa';
        }
        obj.valueOf = function () {
            console.log('調(diào)用了 obj.valueOf');
            return [];
        }

alert(obj+1)缚柏,輸出:調(diào)用了 obj.valueOf。調(diào)用了 obj.toString 碟贾。不報錯币喧。
得出結(jié)論:
對象參與運算時,先調(diào)用其valueOf方法袱耽,若valueOf返回原始值就直接返回杀餐,否則繼續(xù)調(diào)用toString方法,若toString返回不是原始類型朱巨,報錯史翘。

另外注意,===運算,倆個都不調(diào)用琼讽,是個例外必峰。
終上所述,這兩個方法在不同使用場景會有不同的優(yōu)先級:
正常情況下钻蹬,
優(yōu)先調(diào)用toString()吼蚁,有運算操作符的情況下valueOf()的優(yōu)先級高于toString();
當(dāng)調(diào)用valueOf()方法無法運算后還是會再調(diào)用toString()方法;
當(dāng)調(diào)用toString()方法無法的的原始類型后還是會再調(diào)用valueOf()方法问欠。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末肝匆,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子顺献,更是在濱河造成了極大的恐慌术唬,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,607評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件滚澜,死亡現(xiàn)場離奇詭異粗仓,居然都是意外死亡,警方通過查閱死者的電腦和手機设捐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評論 3 395
  • 文/潘曉璐 我一進店門借浊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人萝招,你說我怎么就攤上這事蚂斤。” “怎么了槐沼?”我有些...
    開封第一講書人閱讀 164,960評論 0 355
  • 文/不壞的土叔 我叫張陵曙蒸,是天一觀的道長。 經(jīng)常有香客問我岗钩,道長纽窟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,750評論 1 294
  • 正文 為了忘掉前任兼吓,我火速辦了婚禮臂港,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘视搏。我一直安慰自己审孽,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,764評論 6 392
  • 文/花漫 我一把揭開白布浑娜。 她就那樣靜靜地躺著佑力,像睡著了一般。 火紅的嫁衣襯著肌膚如雪筋遭。 梳的紋絲不亂的頭發(fā)上打颤,一...
    開封第一講書人閱讀 51,604評論 1 305
  • 那天杂数,我揣著相機與錄音,去河邊找鬼瘸洛。 笑死揍移,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的反肋。 我是一名探鬼主播那伐,決...
    沈念sama閱讀 40,347評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼石蔗!你這毒婦竟也來了罕邀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,253評論 0 276
  • 序言:老撾萬榮一對情侶失蹤养距,失蹤者是張志新(化名)和其女友劉穎诉探,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體棍厌,經(jīng)...
    沈念sama閱讀 45,702評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡肾胯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,893評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了耘纱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片敬肚。...
    茶點故事閱讀 40,015評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖束析,靈堂內(nèi)的尸體忽然破棺而出艳馒,到底是詐尸還是另有隱情,我是刑警寧澤员寇,帶...
    沈念sama閱讀 35,734評論 5 346
  • 正文 年R本政府宣布弄慰,位于F島的核電站,受9級特大地震影響蝶锋,放射性物質(zhì)發(fā)生泄漏陆爽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,352評論 3 330
  • 文/蒙蒙 一牲览、第九天 我趴在偏房一處隱蔽的房頂上張望墓陈。 院中可真熱鬧恶守,春花似錦第献、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至衫樊,卻和暖如春飒赃,著一層夾襖步出監(jiān)牢的瞬間利花,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評論 1 270
  • 我被黑心中介騙來泰國打工载佳, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留炒事,地道東北人。 一個月前我還...
    沈念sama閱讀 48,216評論 3 371
  • 正文 我出身青樓蔫慧,卻偏偏與公主長得像挠乳,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子姑躲,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,969評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 第5章 引用類型(返回首頁) 本章內(nèi)容 使用對象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,237評論 0 4
  • 函數(shù)和對象 1睡扬、函數(shù) 1.1 函數(shù)概述 函數(shù)對于任何一門語言來說都是核心的概念。通過函數(shù)可以封裝任意多條語句黍析,而且...
    道無虛閱讀 4,564評論 0 5
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5卖怜? 答:HTML5是最新的HTML標(biāo)準。 注意:講述HT...
    kismetajun閱讀 27,486評論 1 45
  • ??引用類型的值(對象)是引用類型的一個實例。 ??在 ECMAscript 中蔼两,引用類型是一種數(shù)據(jù)結(jié)構(gòu)虑粥,用于將數(shù)...
    霜天曉閱讀 1,056評論 0 1
  • 第3章 基本概念 3.1 語法 3.2 關(guān)鍵字和保留字 3.3 變量 3.4 數(shù)據(jù)類型 5種簡單數(shù)據(jù)類型:Unde...
    RickCole閱讀 5,128評論 0 21