亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JavaScript中Object.prototype.toString方法的原理

 更新時(shí)間:2016年02月24日 10:36:20   作者:紫云飛  
這篇文章主要介紹了JavaScript中Object.prototype.toString方法的原理的相關(guān)資料,需要的朋友可以參考下

在JavaScript中,想要判斷某個(gè)對(duì)象值屬于哪種內(nèi)置類型,最靠譜的做法就是通過(guò)Object.prototype.toString方法.

var arr = [];
console.log(Object.prototype.toString.call(arr)) //"[object Array]"

本文要講的就是,toString方法是如何做到這一點(diǎn)的,原理是什么.

ECMAScript 3

在ES3中,Object.prototype.toString方法的規(guī)范如下:

15.2.4.2 Object.prototype.toString()

在toString方法被調(diào)用時(shí),會(huì)執(zhí)行下面的操作步驟:

1. 獲取this對(duì)象的[[Class]]屬性的值.

2. 計(jì)算出三個(gè)字符串"[object ", 第一步的操作結(jié)果Result(1), 以及 "]"連接后的新字符串.

3. 返回第二步的操作結(jié)果Result(2).

[[Class]]是一個(gè)內(nèi)部屬性,所有的對(duì)象(原生對(duì)象和宿主對(duì)象)都擁有該屬性.在規(guī)范中,[[Class]]是這么定義的

內(nèi)部屬性 描述
[[Class]] 一個(gè)字符串值,表明了該對(duì)象的類型.

然后給了一段解釋:

所有內(nèi)置對(duì)象的[[Class]]屬性的值是由本規(guī)范定義的.所有宿主對(duì)象的[[Class]]屬性的值可以是任意值,甚至可以是內(nèi)置對(duì)象使用過(guò)的[[Class]]屬性的值.[[Class]]屬性的值可以用來(lái)判斷一個(gè)原生對(duì)象屬于哪種內(nèi)置類型.需要注意的是,除了通過(guò)Object.prototype.toString方法之外,本規(guī)范沒(méi)有提供任何其他方式來(lái)讓程序訪問(wèn)該屬性的值(查看 15.2.4.2).

也就是說(shuō),把Object.prototype.toString方法返回的字符串,去掉前面固定的"[object "和后面固定的"]",就是內(nèi)部屬性[[class]]的值,也就達(dá)到了判斷對(duì)象類型的目的.jQuery中的工具方法$.type(),就是干這個(gè)的.

在ES3中,規(guī)范文檔并沒(méi)有總結(jié)出[[class]]內(nèi)部屬性一共有幾種,不過(guò)我們可以自己統(tǒng)計(jì)一下,原生對(duì)象的[[class]]內(nèi)部屬性的值一共有10種.分別是:"Array", "Boolean", "Date", "Error", "Function", "Math", "Number", "Object", "RegExp", "String".

ECMAScript 5

在ES5.1中,除了規(guī)范寫的更詳細(xì)一些以外,Object.prototype.toString方法和[[class]]內(nèi)部屬性的定義上也有一些變化,Object.prototype.toString方法的規(guī)范如下:

15.2.4.2 Object.prototype.toString ( )

在toString方法被調(diào)用時(shí),會(huì)執(zhí)行下面的操作步驟:

如果this的值為undefined,則返回"[object Undefined]".

如果this的值為null,則返回"[object Null]".

讓O成為調(diào)用ToObject(this)的結(jié)果.

讓class成為O的內(nèi)部屬性[[Class]]的值.

返回三個(gè)字符串"[object ", class, 以及 "]"連接后的新字符串.

可以看出,比ES3多了1,2,3步.第1,2步屬于新規(guī)則,比較特殊,因?yàn)?Undefined"和"Null"并不屬于[[class]]屬性的值,需要注意的是,這里和嚴(yán)格模式無(wú)關(guān)(大部分函數(shù)在嚴(yán)格模式下,this的值才會(huì)保持undefined或null,非嚴(yán)格模式下會(huì)自動(dòng)成為全局對(duì)象).第3步并不算是新規(guī)則,因?yàn)樵贓S3的引擎中,也都會(huì)在這一步將三種原始值類型轉(zhuǎn)換成對(duì)應(yīng)的包裝對(duì)象,只是規(guī)范中沒(méi)寫出來(lái).ES5中,[[Class]]屬性的解釋更加詳細(xì):

所有內(nèi)置對(duì)象的[[Class]]屬性的值是由本規(guī)范定義的.所有宿主對(duì)象的[[Class]]屬性的值可以是除了"Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp", "String"之外的的任何字符串.[[Class]]內(nèi)部屬性是引擎內(nèi)部用來(lái)判斷一個(gè)對(duì)象屬于哪種類型的值的.需要注意的是,除了通過(guò)Object.prototype.toString方法之外,本規(guī)范沒(méi)有提供任何其他方式來(lái)讓程序訪問(wèn)該屬性的值(查看 15.2.4.2).

和ES3對(duì)比一下,第一個(gè)差別就是[[class]]內(nèi)部屬性的值多了兩種,成了12種,一種是arguments對(duì)象的[[class]]成了"Arguments",而不是以前的"Object",還有就是多個(gè)了全局對(duì)象JSON,它的[[class]]值為"JSON".第二個(gè)差別就是,宿主對(duì)象的[[class]]內(nèi)部屬性的值,不能和這12種值沖突,不過(guò)在支持ES3的瀏覽器中,貌似也沒(méi)有發(fā)現(xiàn)哪些宿主對(duì)象故意使用那10個(gè)值.

ECMAScript 6

ES6目前還只是工作草案,但能夠肯定的是,[[class]]內(nèi)部屬性沒(méi)有了,取而代之的是另外一個(gè)內(nèi)部屬性[[NativeBrand]].[[NativeBrand]]屬性是這么定義的:

內(nèi)部屬性 屬性值 描述
[[NativeBrand]] 枚舉NativeBrand的一個(gè)成員. 該屬性的值對(duì)應(yīng)一個(gè)標(biāo)志值(tag value),可以用來(lái)區(qū)分原生對(duì)象的類型.

[[NativeBrand]]屬性的解釋:

[[NativeBrand]]內(nèi)部屬性用來(lái)識(shí)別某個(gè)原生對(duì)象是否為符合本規(guī)范的某一種特定類型的對(duì)象.[[NativeBrand]]內(nèi)部屬性的值為下面這些枚舉類型的值中的一個(gè):NativeFunction, NativeArray, StringWrapper, BooleanWrapper, NumberWrapper, NativeMath, NativeDate, NativeRegExp, NativeError, NativeJSON, NativeArguments, NativePrivateName.[[NativeBrand]]內(nèi)部屬性僅用來(lái)區(qū)分區(qū)分特定類型的ECMAScript原生對(duì)象.只有在表10中明確指出的對(duì)象類型才有[[NativeBrand]]內(nèi)部屬性.

表10 — [[NativeBrand]]內(nèi)部屬性的值

屬性值 對(duì)應(yīng)類型
NativeFunction Function objects
NativeArray Array objects
StringWrapper String objects
BooleanWrapper Boolean objects
NumberWrapper Number objects
NativeMath The Math object
NativeDate Date objects
NativeRegExp RegExp objects
NativeError Error objects
NativeJSON The JSON object
NativeArguments Arguments objects
NativePrivateName Private Name objects

可見(jiàn),和[[class]]不同的是,并不是每個(gè)對(duì)象都擁有[[NativeBrand]].同時(shí),Object.prototype.toString方法的規(guī)范也改成了下面這樣:

15.2.4.2 Object.prototype.toString ( )

在toString方法被調(diào)用時(shí),會(huì)執(zhí)行下面的操作步驟:

如果this的值為undefined,則返回"[object Undefined]".

如果this的值為null,則返回"[object Null]".

讓O成為調(diào)用ToObject(this)的結(jié)果.

如果O有[[NativeBrand]]內(nèi)部屬性,讓tag成為表29中對(duì)應(yīng)的值.

否則

讓hasTag成為調(diào)用O的[[HasProperty]]內(nèi)部方法后的結(jié)果,參數(shù)為@@toStringTag.

如果hasTag為false,則讓tag為"Object".

否則,

讓tag成為調(diào)用O的[[Get]]內(nèi)部方法后的結(jié)果,參數(shù)為@@toStringTag.

如果tag是一個(gè)abrupt completion,則讓tag成為NormalCompletion("???").

讓tag成為tag.[[value]].

如果Type(tag)不是字符串,則讓tag成為"???".

如果tag的值為"Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp",或

者"String"中的任一個(gè),則讓tag成為字符串"~"和tag當(dāng)前的值連接后的結(jié)果.

返回三個(gè)字符串"[object ", tag, and "]"連接后的新字符串.

表29 — [[NativeBrand]] 標(biāo)志值

[[NativeBrand]]值 標(biāo)志值
NativeFunction "Function"
NativeArray "Array"
StringWrapper "String"
BooleanWrapper "Boolean"
NumberWrapper "Number"
NativeMath "Math"
NativeDate "Date"
NativeRegExp "RegExp"
NativeError "Error"
NativeJSON "JSON"
NativeArguments "Arguments"

可以看到,在規(guī)范上有了很大的變化,不過(guò)對(duì)于普通用戶來(lái)說(shuō),貌似感覺(jué)不到.

也許你發(fā)現(xiàn)了,ES6里的新類型Map,Set等,都沒(méi)有在表29中.它們?cè)趫?zhí)行toString方法的時(shí)候返回的是什么?

console.log(Object.prototype.toString.call(Map())) //"[object Map]"
console.log(Object.prototype.toString.call(Set())) //"[object Set]"

其中的字符串"Map"是怎么來(lái)的呢:

15.14.5.13 Map.prototype.@@toStringTag

@@toStringTag 屬性的初始值為字符串"Map".

由于ES6的規(guī)范還在制定中,各種相關(guān)規(guī)定都有可能改變,所以如果想了解更多細(xì)節(jié).看看下面這兩個(gè)鏈接,現(xiàn)在只需要知道的是:[[class]]沒(méi)了,使用了更復(fù)雜的機(jī)制.

以上所述是小編給大家分享的JavaScript中Object.prototype.toString方法的原理,希望對(duì)大家有所幫助!

相關(guān)文章

最新評(píng)論