亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

JavaScript高階教程之“==”隱藏下的類型轉換

2019-11-19 11:48:24
字體:
來源:轉載
供稿:網友

拋磚引玉

按照正常的邏輯來說,我們判斷兩個值是否相等會遵循以下規則:


但是我看下面一組值:

[]==0 //true[]==false //true[]==!{} //true[10]==10 //true'0'==false //true''==0 //trueundefined==null //true !null==true //true 

居然沒有按照我們的劇本走,那它比較規則又是什么?下面我就來分析一波。

“==”的比較規則

首先我們先去ECMAScript5.1中文版( http://lzw.me/pages/ecmascrip... )找一下“==”的比較規則,如下:

1.若Type(x)與Type(y)相同, 則
    a.若Type(x)為Undefined, 返回true。
    b.若Type(x)為Null, 返回true。
    c.若Type(x)為Number, 則
        i.若x為NaN, 返回false。
        ii.若y為NaN, 返回false。
        iii.若x與y為相等數值, 返回true。
        iv.若x 為 +0 且 y為−0, 返回true。
        v.若x 為 −0 且 y為+0, 返回true。
        vi返回false。
    d.若Type(x)為String, 則當x和y為完全相同的字符序列(長度相等且相同字符在相同位置)時返回true。 否則, 返回false。
    e.若Type(x)為Boolean, 當x和y為同為true或者同為false時返回true。 否則, 返回false。
    f.當x和y為引用同一對象時返回true。否則,返回false。
2.若x為null且y為undefined, 返回true。
3.若x為undefined且y為null, 返回true。
4.若Type(x) 為 Number 且 Type(y)為String, 返回comparison x == ToNumber(y)的結果。
5.若Type(x) 為 String 且 Type(y)為Number,返回比較ToNumber(x) == y的結果。
6.若Type(x)為Boolean, 返回比較ToNumber(x) == y的結果。
7.若Type(y)為Boolean, 返回比較x == ToNumber(y)的結果。
8.若Type(x)為String或Number,且Type(y)為Object,返回比較x == ToPrimitive(y)的結果。
9.若Type(x)為Object且Type(y)為String或Number, 返回比較ToPrimitive(x) == y的結果。
10.返回 false

看完ECMAScript5.1中文版的介紹之后,相信很多小伙伴的心情應該是這樣的:


別看上面說的有點花里胡哨的,其實我們可以用很簡單的話來總結出來。由于本篇文章核心是“==”是如何進行類型轉換,我就總結一下類型不同的情況下“==”是如何比較的。

  • 當數據類型為Boolean類型或者String類型時,比較時需要轉換成Number類型。
  • 當數據類型為引用類型時,需要轉換成原始數據類型。當轉換后的原始數據類型為Boolean類型或者String類型,則繼續轉換成Number類型。
  • undefined和null跟任何值在“==”下都返回false,但二者在“==”下返回true。

具體流程圖如下:

備注:

Javascript的數據類型可以分為以下兩種:

  • 原始數據類型(null、undefined、Number、String、Boolean、Symbol(Es6才引入的))
  • 引用類型 (Object)

Boolean類型、String類型轉換成Number類型的規則(ToNumber)

Boolean類型

Boolean Number
true 1
false 0

 

String類型

標準的數字格式
如果是標準的數字格式,轉換成Number類型相比不用多說,比如下面這幾個栗子🌰:

"123" => 123"12.34" => 12.34"0.12" => 0.12"-12.34" => -12.34

非標準的數字格式

但是如果是非標準的數據格式,要分兩種情況來考慮:

  • 第一種:只包含數字并且最多只有1個點。
  • 第二種:包含非數字以及含有多個1個點。

只包含數字并且最多只有1個點

這種情況下會首先進行補0和去0的操作,下面看幾個栗子🌰:

"01234" => 1234".1" => 0.1"12." => 12"1.000" => 1"-02.30" => -2.3

包含非數字以及含有多個1個點

這種情況下統統返回NaN,意為“Not a Number”,這里我們要注意一下,NaN還是Number類型,下面看幾個栗子🌰:

"123aa4" => NaN"哈嘍,DD" => NaNtypeof NaN => "numer"

引用類型轉換成原始數據類型的規則(ToPrimitive)

在介紹轉換規則之前,首先我們我們介紹一下引用類型都帶有的兩個方法:

  • Object.prototype.toString
  • Object.prototype.valueOf

這二者都可以將引用類型轉換成原始數據類型,接下來我們對二者做一個詳細的介紹:

Object.prototype.toString

MDN是這樣解釋的:

The toString() method returns a string representing the object.(toString()這個方法返回一個代表這個對象的字符串)

舉個栗子🌰:

const obj = {}console.log(String(obj)) //"[object Object]"obj.toString = function(){ return 'Hello,Teacher Cang!'}console.log(String(obj)) //"Hello,Teacher Cang!"

Object.prototype.valueOf

MDN是這樣解釋的:

The valueOf() method returns the primitive value of the specified object.( valueOf()這個方法返回這個對象的原始數據值)

舉個栗子🌰:

const obj = {}console.log(Number(obj)) //NaNobj.valueOf = function(){ return 12345;}console.log(Number(obj)) //12345

valueOf和toString的優先級

關于這二者的優先級,在不同的情況下有著不同的優先級,下面我們根據不同情況介紹一下。

ToNumber

看個栗子🌰:

const obj = { toString(){ console.log('調用了toString'); return 'Hello,Teacher Cang!'; }, valueOf(){ console.log('調用了valueOf'); return 12345; }}console.log(Number(obj)); 控制臺輸出結果:>>>>>>>>>>>>>>>>>>調用了valueOf12345

通過上面的代碼的運行結果,我們得出這么一個結論:

在ToNumber情況下,valueOf的優先級大于toString。

接下里我們看這么一種情況,如果valueOf返回的并不是原始數據類型會怎么樣。

const obj = { toString(){ console.log('調用了toString'); return 12345; }, valueOf(){ console.log('調用了valueOf'); return {}; }}console.log(Number(obj)); 控制臺輸出結果:>>>>>>>>>>>>>>>>>>調用了valueOf調用了toString12345

從上面的運行結果中,我們可以得出這么一個結論:

在ToNumber情況下,如果valueOf返回的不是原始數據類型,則會自動調用toString。

打破砂鍋問到底,再來一個非常極端的情況,如果說valueOf和toString返回的都不是原始數據類型,這時又該怎么樣呢?同樣,我們繼續看一下運行結果:

const obj = { toString(){  console.log('調用了toString');  return {}; }, valueOf(){  console.log('調用了valueOf');  return {}; }}console.log(Number(obj)); 控制臺輸出結果:>>>>>>>>>>>>>>>>>>調用了valueOf調用了toStringUncaught TypeError: Cannot convert object to primitive value

從上面的運行結果中,我們再次可以得出這么一個結論:

在ToNumber情況下,如果valueOf和toString返回的都不是原始數據類型,那么js會拋出異常,提示無法將引用類型轉換原始數據類型。

根據三組代碼的運行的結果,我們最后總結一下:

在ToNumber情況下,js會優先調用valueOf,如果valueOf返回的不是原始數據類型,則會接著調用toString,如果toString返回的也不是原始數據類型,js會拋出一個異常,提示無法將引用類型轉換原始數據類型。

具體流程圖如下:

ToString

看個栗子🌰:

const obj = { toString(){  console.log('調用了toString');  return 'Hello,Teacher Cang!'; }, valueOf(){  console.log('調用了valueOf');  return 12345; }}console.log(String(obj)); 控制臺輸出結果:>>>>>>>>>>>>>>>>>>調用了toStringHello,Teacher Cang!

通過上面的代碼的運行結果,我們得出這么一個結論:

在ToString情況下,toString的優先級大于valueOf。

同樣我們看一下,toString返回的值不是原始數據類型時會怎樣:

const obj = { toString(){  console.log('調用了toString');  return {}; }, valueOf(){  console.log('調用了valueOf');  return 'Hello,Teacher Cang!'; }}console.log(String(obj)); 控制臺輸出結果:>>>>>>>>>>>>>>>>>>調用了toString調用了valueOfHello,Teacher Cang!

根據運行結果我們可以得出:

在ToString情況下,如果toString返回的不是原始數據類型,則會自動調用valueOf。

最后我們看一下極端情況,二者返回的都不是原始數據類型:

const obj = { toString(){  console.log('調用了toString');  return {}; }, valueOf(){  console.log('調用了valueOf');  return {}; }}console.log(String(obj)); 控制臺輸出結果:>>>>>>>>>>>>>>>>>>調用了toString調用了valueOfUncaught TypeError: Cannot convert object to primitive value

我們又發現:

在ToString情況下,如果toString和valueOf返回的都不是原始數據類型,那么js會拋出異常,提示無法將引用類型轉換原始數據類型。

我們將三個結論綜合一下:

在ToString情況下,js會優先調用toString,如果toString返回的不是原始數據類型,則會接著調用valueOf,如果valueOf返回的也不是原始數據類型,js會拋出一個異常,提示無法將引用類型轉換原始數據類型。

具體流程圖如下:


“==”下的valueOf和toString的優先級

從文章前面我們總結出來“==”的比較流程來看,引用類型轉換成原始數據類型之后,如果是Sting類型的話,還要再次轉成Number類型,因此“==”下的引用類型轉換原始數據類型過程中,遵循ToNumber的優先級規則。

const obj = { toString(){  console.log('調用了toString');  return 'Hello,Teacher Cang!'; }, valueOf(){  console.log('調用了valueOf');  return 12345; }}console.log(obj==12345); 控制臺輸出結果:>>>>>>>>>>>>>>>>>>調用了valueOftrue
const obj = { toString(){  console.log('調用了toString');  return 12345; }, valueOf(){  console.log('調用了valueOf');  return {}; }}console.log(obj==12345); 控制臺輸出結果:>>>>>>>>>>>>>>>>>>調用了valueOf調用了toStringtrue
const obj = { toString(){  console.log('調用了toString');  return {}; }, valueOf(){  console.log('調用了valueOf');  return {}; }}console.log(obj==12345); 控制臺輸出結果:>>>>>>>>>>>>>>>>>>調用了toString調用了valueOfUncaught TypeError: Cannot convert object to primitive value

“==”之外的類型轉換

“==”號只涉及到了ToPrimitive和ToNumber這兩種轉換,ToBoolean和ToString這兩個沒有涉及到的我們也介紹一下。

ToBoolean

對于ToBoolean,我們只需要記住幾個特例是轉成false的,其余的皆為true。

Boolean('') => falseBoolean(undefined) => falseBoolean(null) => falseBoolean(0) => false 

ToString

Number to String

Number轉String之前,首先會做一個去0和補0的操作,然后再去轉成String類型。

String(1.234) => "1.234"String(NaN) => "NaN"String(.1234) => "0.1234"String(1.23400) => "1.234"

Boolean to String

String(true) => "true"String(false) => "false"

null和undefined to String

String(null) => "null"String(undefined) => "undefined"

引用類型 to String

引用類型先ToPrimitive轉換成原始數據類型,若轉換后的原始數據類型不是String類型,再做String類型的轉換。

const obj = { toString(){  console.log('調用了toString');  return true; }}console.log(String(obj))控制臺輸出結果:>>>>>>>>>>>>>>>>>>調用了toString"true"

總結

“==”下的類型轉換,要分為兩種情況來考慮。第一種,原始數據類型;第二種,引用類型。原始數據類型中String類型和Boolean類型是需要轉換成Number類型再去比較的,而引用類型則需要先轉換成原始數據類型再進行后續的轉換。搞清整個流程之后,我們再去理解“==”涉及到的ToNumber和ToPrimitive是如何進行轉換的。按照這樣子的理解步驟走,我們對“==”隱藏下的類型轉換會有比較清晰的認識。另外,“==”不涉及到ToString和ToBoolean的類型轉換,在文章的后面部分我也加上去了,希望可以給小伙伴們一個更加全面的類型轉換的認識。最后附上完整的“==”類型轉換的流程圖:

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對武林網的支持。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲第一区中文字幕| 国产欧美一区二区三区在线| 欧美丝袜第一区| 69av在线播放| 国产激情综合五月久久| 黑人与娇小精品av专区| 国产精品扒开腿做| 亚洲天堂精品在线| 亚洲免费小视频| 日本成人激情视频| 国产精国产精品| 亚洲欧美中文字幕在线一区| 成人国产精品免费视频| 欧美精品做受xxx性少妇| 91视频免费在线| 奇米一区二区三区四区久久| 在线亚洲男人天堂| 尤物yw午夜国产精品视频明星| 最近2019中文字幕第三页视频| 色偷偷噜噜噜亚洲男人| 久久久久久久久久久免费精品| 美女av一区二区三区| 国产亚洲欧美视频| 欧美丝袜美女中出在线| 中文字幕国产精品| 国产在线一区二区三区| 亚洲国产欧美精品| 精品毛片网大全| 国产精品久久久久久久app| 国产亚洲精品美女久久久| 日本中文字幕成人| 欧美激情图片区| 欧美日韩免费一区| 久久99国产精品自在自在app| 欧美在线影院在线视频| 亚洲最大的av网站| 亚洲国产精品电影在线观看| 91在线免费观看网站| 亚洲一区二区久久久久久| 欧美xxxx14xxxxx性爽| 成人免费午夜电影| 国产日韩欧美黄色| 日韩视频一区在线| 国产剧情日韩欧美| 国内免费精品永久在线视频| 久久久久久久久中文字幕| 久久精品视频在线播放| 欧美在线免费看| 国产福利精品在线| 亚洲黄一区二区| 国产97色在线|日韩| 成人国产在线激情| 久热精品视频在线| 国产美女久久精品| 亚洲xxx视频| 国产ts一区二区| 日本精品va在线观看| 国产在线视频2019最新视频| 91美女片黄在线观| 亚洲乱码国产乱码精品精| 亚洲色图13p| 性色av一区二区三区| 亚洲精品自在久久| 国产视频观看一区| 日韩欧美精品网站| 日韩有码片在线观看| 91免费电影网站| 成人午夜两性视频| 日韩av免费看| 91精品视频在线播放| 国产日韩欧美自拍| 日本欧美在线视频| 亚洲美女动态图120秒| 精品亚洲一区二区三区在线播放| 亚洲精品中文字| 欧美色videos| 国产精品久久久久久久电影| 欧美日韩国产成人在线观看| 久久在线视频在线| 欧美亚洲成人xxx| 国产精品免费一区豆花| 亚洲国产天堂网精品网站| 日日骚av一区| 精品一区电影国产| 在线视频欧美性高潮| 国产91在线播放精品91| 欧美激情第6页| 欧美日韩精品中文字幕| 国产在线视频欧美| 成人精品福利视频| 57pao成人永久免费视频| 成人在线观看视频网站| 久久久久久久国产| 日韩欧美有码在线| 日韩电影第一页| 国产成人午夜视频网址| 高清欧美性猛交| 成人国产在线视频| 亚洲精品日韩av| 欧美激情成人在线视频| 色综合五月天导航| 日韩专区在线播放| 国产精品ⅴa在线观看h| 久久躁日日躁aaaaxxxx| 国产视频精品va久久久久久| 欧美一级电影在线| 日韩精品在线视频| 国产亚洲激情视频在线| 亚洲精品按摩视频| 美日韩丰满少妇在线观看| 欧美与黑人午夜性猛交久久久| 中文字幕日韩在线观看| 日韩毛片在线看| 91国自产精品中文字幕亚洲| 精品国产精品自拍| 日韩av理论片| 日韩中文视频免费在线观看| 亚洲欧洲免费视频| 亚洲男人天堂视频| 久久久女人电视剧免费播放下载| 一本大道香蕉久在线播放29| 国产精品成av人在线视午夜片| 久久精品国产91精品亚洲| 久久香蕉国产线看观看网| 欧美日韩亚洲网| 日韩女在线观看| 伦伦影院午夜日韩欧美限制| 国产一区私人高清影院| 这里只有精品丝袜| 91av在线国产| 91免费人成网站在线观看18| 亚洲aa中文字幕| 成人国内精品久久久久一区| 成人午夜黄色影院| 成人国产亚洲精品a区天堂华泰| 欧美电影在线播放| 亚洲欧美国产高清va在线播| 国产亚洲精品久久久久久| 亚洲xxxxx| 久久露脸国产精品| 亚洲第一天堂av| 91av在线免费观看视频| 久久夜色精品亚洲噜噜国产mv| 亚洲国产私拍精品国模在线观看| 国产美女被下药99| 91香蕉国产在线观看| 国产精品日韩在线一区| 久久综合伊人77777尤物| 精品国产老师黑色丝袜高跟鞋| 91地址最新发布| 蜜臀久久99精品久久久无需会员| 久久亚洲国产精品成人av秋霞| 欧美黄色免费网站| 欧美综合国产精品久久丁香| 538国产精品一区二区免费视频| 福利精品视频在线| 国产成人免费91av在线| 亚洲天堂成人在线视频| 亚洲欧美中文日韩在线| 欧美在线视频观看免费网站| 国产精品久久久久久一区二区| 久久久久免费视频| 97福利一区二区| 午夜精品久久久久久99热软件|