国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JS中的關(guān)系比較與相等比較運(yùn)算

paraller / 1491人閱讀

摘要:在中的關(guān)系比較運(yùn)算,指的是像這種大小值的關(guān)系比較。而相等比較,可區(qū)分為標(biāo)準(zhǔn)相等比較與嚴(yán)格相等比較兩大種類(lèi)。

在JS中的關(guān)系比較(Relational Comparison)運(yùn)算,指的是像x < y這種大小值的關(guān)系比較。

而相等比較,可區(qū)分為標(biāo)準(zhǔn)相等(standard equality)比較x == y與嚴(yán)格相等(strict equality)比較x === y兩大種類(lèi)。嚴(yán)格相等比較會(huì)比較左邊與右邊運(yùn)算元的數(shù)據(jù)類(lèi)型,值相等比較則只看值,簡(jiǎn)單的來(lái)說(shuō)是這樣解釋沒(méi)錯(cuò)。

ToPrimitive運(yùn)算的詳細(xì)說(shuō)明可參考: JS中的{} + {}與{} + []的結(jié)果是什么?

不過(guò),這兩種比較實(shí)際上依內(nèi)部設(shè)計(jì)來(lái)說(shuō),并不是那么簡(jiǎn)單。當(dāng)然,在一般的使用情況是不需要考量那么多,本文的說(shuō)明會(huì)涉及許多JS內(nèi)部設(shè)計(jì)的部份,對(duì)于這兩種比較來(lái)作比較徹底的理解,主要的參考數(shù)據(jù)是ECMAScript的標(biāo)準(zhǔn)文件。

嚴(yán)格相等比較(嚴(yán)格相等比較演算)

嚴(yán)格相等比較的演算規(guī)則先理解,主要是因?yàn)樵跇?biāo)準(zhǔn)相等比較(只比較值不比較數(shù)據(jù)類(lèi)型)時(shí),它在演算時(shí)的某些情況下會(huì)跳到嚴(yán)格相等比較的規(guī)則來(lái)。

嚴(yán)格相等比較的演算規(guī)則很容易理解,按照以下的步驟進(jìn)行比較,出自ecma-262 11.9.6:

以下假設(shè)為比較 x === y的情況,Type(x)指的是x的數(shù)據(jù)類(lèi)型,Type(y)指的是y的類(lèi)型,最終返回值只有true或false,會(huì)按照下面的步驟進(jìn)行比較,如果有返回時(shí)就停止之后的步驟:

注: Type(x)在ECMAScript的標(biāo)準(zhǔn)中指的并不是用typeof返回出來(lái)的結(jié)果,而是標(biāo)準(zhǔn)內(nèi)部給定的各種數(shù)據(jù)類(lèi)型,共有Undefined, Null, Boolean, String, Number 與 Object。例如typeof null的結(jié)果是"object",但ECMAScript會(huì)認(rèn)為Null是個(gè)獨(dú)立的數(shù)據(jù)類(lèi)型。

Type(x)與Type(y)不同,返回false

Type(x)是Undefined,返回true(當(dāng)然此時(shí)Type(y)也是Undefined)

Type(x)是Null,返回true(當(dāng)然此時(shí)Type(y)也是Null)

Type(x)是Number時(shí)

(a.) x是NaN,返回false

(b.) y是NaN,返回false

(c.) x與y是同樣的數(shù)字,返回true

(d.) x是+0,y是-0,返回true

(e.) x是-0,y是+0,返回true

(f.) 其他情況,返回false

Type(x)是String時(shí),只有當(dāng)x中的字符順序與y中完全相同時(shí)(長(zhǎng)度相同,字符所在位置也相同),返回true。其他情況就返回false。

Type(x)是Boolean時(shí),只有當(dāng)x與y是同時(shí)為true或同時(shí)為false時(shí),返回true。其它情況返回false。

只有當(dāng)x與y同時(shí)參照到同一對(duì)象時(shí),返回true。其它情況返回false。

備注: 這個(gè)演算與the SameValue Algorithm (9.12)不同之處在于,對(duì)于有號(hào)的0與NaN處理方式不同。

注: 同值演算(the SameValue Algorithm)是標(biāo)準(zhǔn)中的另一個(gè)內(nèi)部演算法,只會(huì)用在很特別的地方,可以先略過(guò)不看。

從上述的嚴(yán)格相等比較中,可以很清楚的看到數(shù)字、字符串、布爾與null、undefined或?qū)ο笫侨绾伪容^的。

標(biāo)準(zhǔn)相等比較(抽象相等比較演算)

標(biāo)準(zhǔn)相等比較的演算規(guī)則按照以下的步驟進(jìn)行比較,出自ecma-262 11.9.3:

以下假設(shè)為比較 x == y的情況,Type(x)指的是x的數(shù)據(jù)類(lèi)型,Type(y)指的是y的類(lèi)型,最終返回值只有true或false,會(huì)按照下面的步驟進(jìn)行比較,如果有返回時(shí)就停止之后的步驟:

Type(x)與Type(y)相同時(shí),進(jìn)行嚴(yán)格相等比較

x是undefined,而y是null時(shí),返回true

x是null,而y是undefined時(shí),返回true

Type(x)是Number而Type(y)是String時(shí),進(jìn)行x == ToNumber(y)比較

Type(x)是String而Type(y)是Number時(shí),進(jìn)行ToNumber(x) == y比較

Type(x)是Boolean時(shí),進(jìn)行ToNumber(x) == y

Type(y)是Boolean時(shí),進(jìn)行x == ToNumber(y)

Type(x)是Number或String其中一種,而Type(y)是個(gè)Object時(shí),進(jìn)行x == ToPrimitive(y)比較

Type(x)是個(gè)Object,而Type(y)是Number或String其中一種時(shí),進(jìn)行ToPrimitive(x) == y比較

其他情況,返回false

備注1: 以下的是三種強(qiáng)制轉(zhuǎn)換的標(biāo)準(zhǔn)比較情況:

字符串比較: "" + a == "" + b.

數(shù)字比較: +a == +b.

布爾比較: !a == !b

備注2: 標(biāo)準(zhǔn)相等比較有以下的不變式(invariants):

A != B 相當(dāng)于 !(A == B)

A == B 相當(dāng)于 B == A

備注3: 相等比較運(yùn)算不一定總是可以轉(zhuǎn)變(transitive),例如:

new String("a") == "a" 與 "a" == new String("a") 的結(jié)果都是true

new String("a") == new String("a") 結(jié)果是false.

備注4: 字符串比較使用的是簡(jiǎn)單的字符測(cè)試。并非使用復(fù)雜的、語(yǔ)義導(dǎo)向的字符定義或是Unicode所定義的字符串相等或校對(duì)順序。

注: 上述的ToNumber與ToPrimitive都是標(biāo)準(zhǔn)內(nèi)部運(yùn)算時(shí)使用的方法,并不是讓開(kāi)發(fā)者使用的。

由標(biāo)準(zhǔn)相等比較的演算得知,它的運(yùn)算是以"數(shù)字為最優(yōu)先",任何其它的類(lèi)型如果與數(shù)字作相等比較,必定要先強(qiáng)制轉(zhuǎn)為數(shù)字再比較。但這是一個(gè)相當(dāng)具有隱藏作用的運(yùn)算,在一般實(shí)作時(shí),會(huì)很容易造成誤解,例如以下的例子:

> 0 == []
true

> "" == []
true

上面這是因?yàn)榭諗?shù)組[],進(jìn)行ToPrimitive運(yùn)算后,得到的是空字符串,所以作值相等比較,相當(dāng)于空字符串在進(jìn)行比較。

> "[object Object]" == {}
true

> NaN == {}
false

上面的空對(duì)象字面量,進(jìn)行ToPrimitive運(yùn)算后,得到的是"[object Object]"字符串,這個(gè)值會(huì)如果與數(shù)字類(lèi)型的NaN比較,會(huì)跳到同類(lèi)型相等的嚴(yán)格相等比較中,NaN不論與任何數(shù)字作相等比較,一定是返回false。

> 1 == new Number(1)
true

> 1 === new Number(1)
false

> 1 === Number(1)
true

上面說(shuō)明了,包裝對(duì)象在JS中的內(nèi)部設(shè)計(jì)中,標(biāo)準(zhǔn)的值相等比較是相同的,但嚴(yán)格相等比較是不同的值,包裝對(duì)象仍然是個(gè)對(duì)象,只是里面的valueOf方法是返回這個(gè)對(duì)象里面帶的原始數(shù)據(jù)類(lèi)型值,經(jīng)過(guò)ToPrimitive方法運(yùn)算后,會(huì)返回原始數(shù)據(jù)的值。Number()函數(shù)調(diào)用只是轉(zhuǎn)數(shù)字類(lèi)型用的函數(shù),這個(gè)用法經(jīng)常會(huì)與包裝對(duì)象的用法混在一起。

這個(gè)小節(jié)的結(jié)論是,在JS中沒(méi)有必要的情況下,使用嚴(yán)格的相等比較為最佳的值相等比較方式,標(biāo)準(zhǔn)的相等容易產(chǎn)生不經(jīng)意的副作用,有的時(shí)候你可能會(huì)得到不預(yù)期的結(jié)果。

關(guān)系比較(抽象關(guān)系比較演算)

關(guān)系比較的演算規(guī)則主要是按照以下的步驟進(jìn)行比較,出自ecma-262 11.8.5:

以下假設(shè)為比較 x < y的情況,因?yàn)樵跇?biāo)準(zhǔn)中的抽象關(guān)系比較演算的說(shuō)明比較復(fù)雜,有涉及布爾標(biāo)記的以左方優(yōu)先或右方優(yōu)先,而且最終返回值有true、false與undefined,實(shí)際上最終不會(huì)有undefined值出現(xiàn),即是得到false而已,以下為只考慮左方優(yōu)先(LeftFirst)的簡(jiǎn)化過(guò)的步驟。會(huì)按照下面的步驟進(jìn)行比較,如果有返回時(shí)就停止之后的步驟:

(1. & 2.) x經(jīng)過(guò)ToPrimitive(x, hint Number)運(yùn)算為px值,y經(jīng)過(guò)ToPrimitive(y, hint Number)運(yùn)算為py值

(3.) 如果Type(px)與Type(py)不同時(shí)為String時(shí)

(a.b.) px作ToNumber(px)運(yùn)算,得到nx值,與py作ToNumber(py)值,得到ny值

(c.d.) nx或ny中有其一為NaN時(shí),返回undefined

(e.) nx與ny是同樣的Number值,返回false

(f.) nx是+0,而且ny是?0,返回false

(g.) nx是?0,而且ny是+0,返回false.

(h.) nx是+∞,返回false

(i.) ny是+∞,返回true

(j.) ny是?∞,返回false

(k.) nx是?∞,返回true

(l.) 如果在數(shù)學(xué)上的值,nx小于ny,而且nx與ny是有限值(finite),而且不同時(shí)為0時(shí),返回true。否則返回false。

(4.) 如果Type(px)與Type(py)同時(shí)為String時(shí)

(a.) 如果py是px的前綴(prefix)時(shí),返回false (前綴代表px字符串中是由py字符串組成的,py只是px的子字符串的情況)

(b.) 如果px是py的前綴(prefix)時(shí),返回true

(c.d.e.f) 以字符串中的按順序的字符,用字符的編碼整數(shù)的大小來(lái)比較。k是可得到的一個(gè)最小非負(fù)整數(shù),在px與py中的k位置有不同的字符(從左邊算過(guò)來(lái))。在px中某個(gè)位置k的字符編碼整數(shù)為m,在py某個(gè)位置k的字符編輯為n,如果m < n,則返回true,否則返回false

備注2: 字符串比較使用的是簡(jiǎn)單的詞典順序測(cè)試。并非使用復(fù)雜的、語(yǔ)義導(dǎo)向的字符定義或是Unicode所定義的字符串相等或校對(duì)順序。

注: +∞相當(dāng)于全局屬性InfinityNumber.POSITIVE_INFINITY?∞相當(dāng)于全局屬性-InfinityNumber.NEGATIVE_INFINITY

關(guān)系比較基本上要區(qū)分為數(shù)字類(lèi)型與字符串類(lèi)型,但依然是以"數(shù)字"為最優(yōu)先的比較,只要有其他類(lèi)型與數(shù)字相比較,一定會(huì)先被強(qiáng)制轉(zhuǎn)換為數(shù)字。但在這之前,需要先用ToPrimitive而且是hint為數(shù)字來(lái)轉(zhuǎn)換為原始數(shù)據(jù)類(lèi)型。

以下為一些與對(duì)象、數(shù)組、Date對(duì)象的關(guān)系比較例子:

> 1 < (new Date())
true

> 1 > (new Date())
false

> [] < 1
true

> [] > 1
false

> ({}) < 1
false

> ({}) > 1
false

雖然在標(biāo)準(zhǔn)中的抽象關(guān)系比較演算中,有存在一種返回值undefined,但在真實(shí)的情況并沒(méi)有這種返回值,相當(dāng)不論怎么比較都是得到false的值。上面的例子中,空對(duì)象({})的ToPrimitive運(yùn)算得出的是"[object Object]"字符串值,經(jīng)過(guò)ToNumber運(yùn)算會(huì)得到NaN數(shù)字類(lèi)型的值,這個(gè)值不論與數(shù)字1作大于小于的關(guān)系運(yùn)算,都是false。

Date()對(duì)象因?yàn)?b>ToPrimitive運(yùn)算的hint為數(shù)字,所以也是會(huì)作轉(zhuǎn)換為數(shù)字類(lèi)型的值為優(yōu)先(也就是調(diào)用valueOf為優(yōu)先),所以并不是正常情況的以輸出字符串為優(yōu)先(也就是調(diào)用toString方法為優(yōu)先)的預(yù)設(shè)情況。

以下為一些字符串關(guān)系比較的例子:

> "a" > ""
true

> "a" < ""
false

> "a" > []
true

> "a" < []
false

> "a" > ({})
true

> "a" < ({})
false

字符串與空字符串相比,都是套用前綴(prefix)的規(guī)則步驟,因?yàn)榭兆址闶撬凶址那熬Y(組成的子字符串之一),所以必然地所有有值的字符串值一定是大于空字符串。

空數(shù)組經(jīng)過(guò)ToPrimitive運(yùn)算出來(lái)的是空字符串,所以與空字符串相比較的結(jié)果相同。

空對(duì)象經(jīng)過(guò)ToPrimitive運(yùn)算出來(lái)的是"[object Object]"字符串值,以"a".charCodeAt(0)計(jì)算出的值是字符編碼是97數(shù)字,而"[".charCodeAt(0)則是91數(shù)字,所以"a" > ({})會(huì)是得到true。

如果開(kāi)始混用數(shù)字與字符串比較,可能是有陷阱的比較例子:

> "11" > "3"
false

> "11" > 3
true

> "one" < 3
false

> "one" > 3
false

"11"與"3"相比較,其實(shí)都是字符串比較,要依照可比較的字符位置來(lái)比較,也就是"1"與"3"字符的比較,它們的字符編碼數(shù)字分別是49與51,所以"1" < "3",這里的運(yùn)算的結(jié)果必然是返回false。

"11"與3數(shù)字比較,是會(huì)強(qiáng)制都轉(zhuǎn)為數(shù)字來(lái)比較,"11"會(huì)轉(zhuǎn)為11數(shù)字值,所以大于3。

"one"這個(gè)字符串轉(zhuǎn)為數(shù)字后,是NaN這個(gè)數(shù)字值,NaN與任何數(shù)字比較,既不大于也不小于,不論作大于或小于,都是返回false。(實(shí)際上在標(biāo)準(zhǔn)中它這種返回值叫undefined)

字符串與數(shù)字之外其他的原始數(shù)據(jù)類(lèi)型的比較,只要記得原則就是強(qiáng)制轉(zhuǎn)為數(shù)字來(lái)比較就是了,以下為例子:

> true > null
true

> false > undefined
false

簡(jiǎn)單地說(shuō)明在ToNumber運(yùn)算時(shí),這些其他的原始數(shù)據(jù)類(lèi)型值的轉(zhuǎn)換結(jié)果如下:

Undefined -> NaN

Null -> +0

Boolean -> (true -> 1, false -> 0)

注: JS認(rèn)為+0與-0是完全相同的值,在嚴(yán)格相等比較中是相等的。

注: 字符串比較實(shí)際上是拆為字符在詞典表中的編輯整數(shù)值來(lái)比較,對(duì)于非英語(yǔ)系的語(yǔ)言,JS另外有提供String.prototype.localeCompare的方法來(lái)進(jìn)行局部語(yǔ)言的比較工作。

總結(jié)

本章延伸了之前的加法運(yùn)算文章中的ToPrimitive運(yùn)算解說(shuō)的部份,較為仔細(xì)的來(lái)研究JS中的相等比較(包含標(biāo)準(zhǔn)的與嚴(yán)格的)與關(guān)系比較的部份。至于沒(méi)提到的,不相等(==)與嚴(yán)格不相等(!==),或是大于等于(>=)或小于等于(<=)只是這些演算規(guī)劃的再組合結(jié)果而已。

標(biāo)準(zhǔn)的值相等比較(==),是一種有不經(jīng)意的副作用的運(yùn)算,不管如何,開(kāi)發(fā)者必定要盡量避免,比較前可以自行轉(zhuǎn)換類(lèi)型的方式,再作嚴(yán)格的相等比較,本章也有說(shuō)明為何要避免使用它的理由。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/88092.html

相關(guān)文章

  • JS基礎(chǔ)學(xué)習(xí)03「表達(dá)式和運(yùn)算符」

    摘要:函數(shù)定義表達(dá)式。對(duì)象創(chuàng)建表達(dá)式。需要注意的是,大多數(shù)運(yùn)算符都是由標(biāo)點(diǎn)符號(hào)表示的,比如和。也就是說(shuō),空字符串將被當(dāng)作,布爾值將被當(dāng)作。對(duì)于和,則分別調(diào)用函數(shù)并取得字符串和。 表達(dá)式 表達(dá)式是由數(shù)字、運(yùn)算符、數(shù)字分組符號(hào)(如括號(hào))、自由變量和約束變量等以能求得數(shù)值的有意義排列方法所得的組合。JavaScript 表達(dá)式主要有以下幾種形式: 原始表達(dá)式:常量、變量、保留字。 對(duì)象、數(shù)組初始...

    dcr309duan 評(píng)論0 收藏0
  • 《javascript高級(jí)程序設(shè)計(jì)》筆記:關(guān)系運(yùn)算相等運(yùn)算

    摘要:要比較相等性之前,不能將和轉(zhuǎn)換成其他任何值。如果有一個(gè)操作數(shù)是,則相等操作符返回,而不相等操作符返回。重要提示即使兩個(gè)操作數(shù)都是,相等操作符也返回因?yàn)榘凑找?guī)則,不等于。 關(guān)系運(yùn)算符 關(guān)系運(yùn)算符有小于()、小于等于(=)四種,它們都返回一個(gè)布爾值 《javascript高級(jí)程序設(shè)計(jì)》書(shū)中的規(guī)則是這樣描述運(yùn)算規(guī)則: (1)如果兩個(gè)操作數(shù)都是數(shù)值,則執(zhí)行數(shù)值比較; (2)如果兩個(gè)操作數(shù)都是字...

    Blackjun 評(píng)論0 收藏0
  • javascript基礎(chǔ)

    摘要:一彈窗和輸出執(zhí)行順序是從上到下執(zhí)行控制瀏覽器彈出一個(gè)警告框讓計(jì)算機(jī)在頁(yè)面中輸出一個(gè)內(nèi)容在中寫(xiě)一個(gè)內(nèi)容寫(xiě)可以向中輸出一個(gè)內(nèi)容看我出不出來(lái)向控制臺(tái)輸出一個(gè)內(nèi)容作用是向控制臺(tái)輸出一個(gè)內(nèi)容你猜我在哪出來(lái)二編寫(xiě)位置可以將代碼編寫(xiě)到外部文件中,然后通過(guò) 一.彈窗和輸出 **javascript執(zhí)行順序是從上到下執(zhí)行** 1.控制瀏覽器彈出一個(gè)警告框 alert(HelloWord); 2.讓計(jì)...

    XFLY 評(píng)論0 收藏0
  • js面試題(下)

    摘要:短路運(yùn)算返回值是什么又稱為短路或,短路如果左側(cè)為真,則不再進(jìn)行右側(cè)運(yùn)算,同時(shí)返回左側(cè)表達(dá)式運(yùn)算結(jié)果。上面是不存在的,所有結(jié)果為,轉(zhuǎn)成就是,那么就會(huì)運(yùn)算,把賦值給的同時(shí),返回值也是,所以打印返回結(jié)果是函數(shù)內(nèi)部變量有哪些 DOM元素e的e.getAttribute(propName)和e.propName有什么區(qū)別和聯(lián)系 e.getAttribute(),是標(biāo)準(zhǔn)DOM操作文檔元素屬性的方...

    zhoutao 評(píng)論0 收藏0
  • 溫故js系列(4)-運(yùn)算符詳解

    摘要:一元運(yùn)算符一元運(yùn)算符只能操作一個(gè)值。邏輯非邏輯非參考數(shù)據(jù)判斷邏輯非運(yùn)算符可以用于任何值。無(wú)論這個(gè)值是什么數(shù)據(jù)類(lèi)型,這個(gè)運(yùn)算符都會(huì)返回一個(gè)布爾值。 前端學(xué)習(xí):教程&開(kāi)發(fā)模塊化/規(guī)范化/工程化/優(yōu)化&工具/調(diào)試&值得關(guān)注的博客/Git&面試-前端資源匯總 歡迎提issues斧正:運(yùn)算符 JavaScript-運(yùn)算符 JavaScript 有一系列操作數(shù)據(jù)值的運(yùn)算符,運(yùn)算符按照特定運(yùn)算規(guī)則對(duì)...

    王軍 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<