toString()和Object.prototype.toString.call()

1.toString()

它的作用是:將某一個(gè)值轉(zhuǎn)化為字符串
我們先看個(gè)demo:

var t1 = {a: 1};
var t2 = [1,2];
var t3 = 'str';
var t4= 5
var t5=true
console.log(t1.toString())  //"[object Object]"
console.log(t2.toString())  //"1,2"
console.log(t3.toString())  // "str"
console.log(t4.toString())  // "4"
console.log(t5.toString())  // "true"

在上面的例子中盏缤,我們定義了對象茫舶、數(shù)組陕习、字符串三個(gè)類型來調(diào)用toString方法垢夹,但是結(jié)果卻完全不一樣猛拴。奇怪仁热?

從例子上看揍很,

  • 對象返回的是貌似可以反映出其類型的字符串
  • 數(shù)組返回的是字符串列表
  • 字符串返回的是字符串副本(即原樣輸出)

所以從結(jié)果看融柬,貌似不同類型的toString的方法功能不一樣(雖然名字都叫toString)。

了解過對象原型以及基本包裝類型的朋友都知道煎娇,上面例子中:

  • t1調(diào)用的是Object.prototype里的方法
  • t2調(diào)用的是Array.prototype里的方法
  • t3調(diào)用的是String.prototype里的方法

雖然t2也是對象二庵,但其原型鏈上的第一層Array.prototype就有toString方法,所以就會(huì)直接繼承缓呛,而不會(huì)再去找Array.prototype.__proto__即Object.prototype中的toString方法催享,所以不同類型的原型鏈?zhǔn)交蚨嗷蛏俣?重寫了toString方法,所以功能用處都不一樣哟绊。

接下來因妙,我們再來分析一下不同類型調(diào)用toString()方法,返回值有什么不同之處?

1.1.字符串string(即調(diào)用 new String出來的基本包裝類型的方法)

返回字符串的一個(gè)副本(即原樣輸出)

var str = "a";
str.toString(); //"a"
String.prototype.toString.call(str) // "a"

1.2.數(shù)值number(即調(diào)用 new Number出來的基本包裝類型的方法)

返回字符串形式的數(shù)值

var num = 520;
num.toString(); //"520"
Number.prototype.toString.call(num) // "a"

1.3.布爾值boolean(即調(diào)用 new Boolean出來的基本包裝類型的方法)

返回字符串"true"或"false"

var boo = true;
boo.toString(); //"true"
Boolean.prototype.toString.call(boo); //"true"

1.4.獨(dú)一無二值symbol(即調(diào)用構(gòu)造函數(shù)Symbol生成的實(shí)例方法攀涵,注這里調(diào)用和一般的構(gòu)造函數(shù)不一樣铣耘,不需要new,直接調(diào)用)

返回字符串"Symbol()"

var symbol = Symbol();
symbol.toString(); //"Symbol()"
Symbol.prototype.toString.call(symbol); //"Symbol()"

1.5.null和undefined

null和undefined沒有相應(yīng)的構(gòu)造函數(shù)以故,所以它們沒有也無法調(diào)用toString()方法蜗细,也就是說它們不能訪問任何屬性和方法,只是基本類型而已怒详。

16.對象object(即調(diào)用Object.prototype的方法)

返回 [object type]炉媒,其中type為對象的類型

var t1 = {a: 1};
t1.toString()  //"[object Object]"
Object.prototype.toString.call(t1); //"[object Object]"

1.7.數(shù)組Array(即調(diào)用Array.prototype的方法)

返回由數(shù)組中每個(gè)值的字符串形式 拼接而成的一個(gè)以逗號分隔的字符串

var array = [1, 's', true, {a: 2}];
array.toString();//"1,s,true,[object Object]"
Array.prototype.toString.call(array);//"1,s,true,[object Object]"

1.8.函數(shù)function(即調(diào)用Function.prototype的方法)

返回函數(shù)的代碼

function foo(){
    console.log(1');
};
foo.toString();
<!--"function foo(){-->
<!--    console.log(1);-->
<!--}"-->
Function.prototype.toString.call(foo);
<!--"function foo(){-->
<!--    console.log(1');-->
<!--}"-->

所以:

Object.toString();
//"function Object() { [native code] }"
Function.toString();
//"function Function() { [native code] }"
Array.toString();
//"function Array() { [native code] }"
....

因?yàn)?/p>

Array.__proto__===Function.prototype  //true
Object.__proto__===Function.prototype  //true
Function.__proto__===Function.prototype  //true

1.9.日期Date(即調(diào)用Date.prototype的方法)

返回帶有時(shí)區(qū)信息的日期和時(shí)間

var date = new Date();
date.toString();
//"Fri May 11 2018 14:55:43 GMT+0800 (中國標(biāo)準(zhǔn)時(shí)間)"
Date.prototype.toString.call(date);
//"Fri May 11 2018 14:55:43 GMT+0800 (中國標(biāo)準(zhǔn)時(shí)間)"

1.10.正則表達(dá)式RegExp(即調(diào)用RegExp.prototype的方法)

返回正則表達(dá)式的字符串形式

var re = /cat/g;
re.toString();// "/cat/g"
RegExp.prototype.toString.call(re);// "/cat/g"

1.11.全局對象window

返回 [object window]

window.toString(); //"[object Window]"
Object.prototype.toString.call(window); //"[object Window]"

window是js中的特殊對象,Window并不是個(gè)構(gòu)造函數(shù)昆烁,也就是說并沒有Window.prototype原型對象上重寫toString()方法吊骤,它會(huì)順著原型鏈查找調(diào)用Object.prototype.toString()。

2.Object.prototype.toString.call( )

上面我們通過直接調(diào)用和call調(diào)用兩種方式進(jìn)行toString方法測試静尼。我們知道對應(yīng)object返回的結(jié)果是[object type]白粉,其中type為對象的類型`,那么我們可以根據(jù)其返回對象的功能進(jìn)行類型判斷鼠渺。

Object.prototype.toString.call({});
<!--"[object Object]"-->
Object.prototype.toString.call([]);
<!--"[object Array]"-->
Object.prototype.toString.call(function(){});
<!--"[object Function]"-->
Object.prototype.toString.call('');
<!--"[object String]"-->
Object.prototype.toString.call(1);
<!--"[object Number]"-->
Object.prototype.toString.call(true);
<!--"[object Boolean]"-->
Object.prototype.toString.call(null);
<!--"[object Null]"-->
Object.prototype.toString.call(undefined);
<!--"[object Undefined]"-->
Object.prototype.toString.call();
<!--"[object Undefined]"-->
Object.prototype.toString.call(new Date());
<!--"[object Date]"-->
Object.prototype.toString.call(/at/);
<!--"[object RegExp]"-->

3.直接調(diào)用

toString();
<!--"[object Undefined]"-->

(function(){
    console.log(toString());
})();
<!--[object Undefined]-->

也就是說直接調(diào)用toString()方法鸭巴,等價(jià)于

Object.prototype.toString.call();
<!--"[object Undefined]"-->
Object.prototype.toString.call(undefined);
<!--"[object Undefined]"-->

即:直接調(diào)用toString()方法這里不可以理解成為全局作用域調(diào)用toString()方法,即window.toString()

所以直接調(diào)用toString()應(yīng)該就是變相的undefined.toString()方法(這里說的是相當(dāng)于系冗,實(shí)際undefined并沒有方法奕扣,調(diào)用會(huì)報(bào)錯(cuò))。

4.toString.call/apply(類型)

經(jīng)常有人用toString.call/apply(類型)去代替Object.prototype.toString.call/apply(類型)使用掌敬,其實(shí)這樣是不嚴(yán)謹(jǐn)?shù)模菀讓?dǎo)致一些問題池磁,如下所示

function toString(){
    console.log(1")
}
toString();//1
toString.call({});//1
toString.call([]);//1

我們可以發(fā)現(xiàn)奔害,當(dāng)我們自定義了toString()方法時(shí),直接調(diào)用toString()方法地熄,就不會(huì)再默認(rèn)調(diào)用Object類的toString()方法华临,而是會(huì)使用我們自定義的方法,這樣可能得不到我們想要的結(jié)果端考,所以我們還是應(yīng)當(dāng)盡量使用Object.prototype.toString.call/apply(類型)雅潭。

5.類型

類似toString()方法,Object的不同子類型還重寫了toLocaleString()却特、valueOf()等方法扶供,這里我想說的是不管對象子類型怎么重寫方法,只要我們明白這些方法是哪里來的裂明,怎么調(diào)用的椿浓,就能很好的理解這些方法調(diào)用后產(chǎn)生的結(jié)果!

說到底,對JS中對象和原型的理解真的非常非常重要扳碍!

6.參考

由Object.prototype.toString.call( )引發(fā)關(guān)于toString( )方法的思考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末提岔,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子笋敞,更是在濱河造成了極大的恐慌碱蒙,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件夯巷,死亡現(xiàn)場離奇詭異赛惩,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)鞭莽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進(jìn)店門坊秸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人澎怒,你說我怎么就攤上這事褒搔。” “怎么了喷面?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵星瘾,是天一觀的道長。 經(jīng)常有香客問我惧辈,道長琳状,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任盒齿,我火速辦了婚禮念逞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘边翁。我一直安慰自己翎承,他們只是感情好符匾,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布叨咖。 她就那樣靜靜地躺著,像睡著了一般啊胶。 火紅的嫁衣襯著肌膚如雪甸各。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天焰坪,我揣著相機(jī)與錄音趣倾,去河邊找鬼。 笑死琳彩,一個(gè)胖子當(dāng)著我的面吹牛誊酌,可吹牛的內(nèi)容都是我干的部凑。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼碧浊,長吁一口氣:“原來是場噩夢啊……” “哼涂邀!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起箱锐,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤比勉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后驹止,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體浩聋,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年臊恋,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了衣洁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,064評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡抖仅,死狀恐怖坊夫,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情撤卢,我是刑警寧澤环凿,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站放吩,受9級特大地震影響智听,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜渡紫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一到推、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧惕澎,春花似錦环肘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽复哆。三九已至欣喧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間梯找,已是汗流浹背唆阿。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留锈锤,地道東北人驯鳖。 一個(gè)月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓闲询,卻偏偏與公主長得像,于是被迫代替她去往敵國和親浅辙。 傳聞我的和親對象是個(gè)殘疾皇子扭弧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評論 2 345

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

  • ??引用類型的值(對象)是引用類型的一個(gè)實(shí)例鸽捻。 ??在 ECMAscript 中,引用類型是一種數(shù)據(jù)結(jié)構(gòu)泽腮,用于將數(shù)...
    霜天曉閱讀 1,036評論 0 1
  • 第5章 引用類型(返回首頁) 本章內(nèi)容 使用對象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,212評論 0 4
  • 第3章 基本概念 3.1 語法 3.2 關(guān)鍵字和保留字 3.3 變量 3.4 數(shù)據(jù)類型 5種簡單數(shù)據(jù)類型:Unde...
    RickCole閱讀 5,097評論 0 21
  • 概述 JavaScript 原生提供Object對象(注意起首的O是大寫)御蒲,本章介紹該對象原生的各種方法。 Jav...
    許先生__閱讀 462評論 0 3
  • 概述 JavaScript 原生提供Object對象诊赊。JavaScript 的所有其他對象都繼承自O(shè)bject對象...
    oWSQo閱讀 272評論 0 1