摘要:中抽象相等比較算法大致介紹一下的數據類型的數據類型分為種如果再加上數據類型,一共種與的區別描述一個空值空的對象引用即空指針,被當做一個對象,輸出為算是一個吧,輸出為。運算符把其值參數轉換為非類型對象。
Javascript中抽象相等比較算法
undefined==null //true []==[] //false []==![] //true {}==!{} //false ![]=={} //false []==!{} //true [1,2]==![1] //false大致介紹一下JS的數據類型
ES5的數據類型分為6種:Undefined Null String Number Boolean Object,如果再加上ES6Symbol數據類型,一共7種;
null與undefined的區別:
null描述一個空值(空的對象引用即空指針),null被當做一個對象,typeOf null輸出為"Object"(算是一個bug吧),Number(null)輸出為0。undefined是預定義的全局變量,表示“缺少值”,typeOf undefined輸出為"undefined",Number(undefined)輸出為NaN;
null是一個關鍵字,而undefined并不是一個關鍵字;
原始值概念js的數據類型其實可以分為兩種:原始類型和引用類型。原始類型又稱簡單類型和基本類型,包括Undefined、Null、Boolean、Number和String五種。引用類型又稱復雜類型,即Object;原始類型和引用類型分別稱為原始值和復雜值;
簡單的說:原始值是固定而簡單的值,是存放在棧(stack)中的簡單數據段,也就是說,它們的值直接存儲在變量訪問的位置,原始類型的值被稱為原始值
原始類型(primitive type)有以下五種類型:Undefined,Null,Boolean,Number,String
typeOf運算符:
條件 | 返回值 |
---|---|
如果變量是undefined類型 | undefined |
如果變量是Boolean類型 | boolean |
如果變量是Number類型 | number |
如果變量是String類型 | string |
如果變量是Null類型 | object |
如果變量是引用類型 | object |
用Type(z)代表z的數據類型,比較運算 x==y,其中x和y是值,產生true或false。 1.Type(x)與Type(y)相同: a.如果Type(x)為Undefined或Null,則返回true b.如果Type(x)為Number,則: i.若x為NaN,返回false ii.若y為NaN,返回false iii.若x與y數值相等,返回true iiii.若x為+0,y為-0,返回true iv.若x為-0,y為+0,返回true v.返回false c.如果Type(x)為String,則x和y對應位置的字符完全一樣才返回true,否則返回false, d.如果Type(x)為Boolean,則相同值返回true,否則false f.當x和y引用同一對象時,返回true,否則,返回false 2.x為undefined,y為null,返回true,反之亦然 3. Type(x)為String,Type(y)為Number,則返回比較ToNumber(x) == y,反之亦然 4.Type(x)為Boolean,則返回比較ToNumber(x)==y的結果,反之亦然 5.Type(x)為String或Number,Type(y)為Object,則返回比較ToPrimitive(y) == x 6.返回false
再來看看ToBoolean,ToNumber,ToPrimitive三個運算符的定義:
輸入類型 | 結果 |
---|---|
Undefined | false |
Null | false |
Boolean | 不轉換 |
Number | 如果參數是-0,+0或NaN,結果為false,否則為true |
String | 如果參數是空字符串(長度為零),結果為false,否則為true |
Object | true |
輸入類型 | 結果 |
---|---|
Undefined | NaN |
Null | +0 |
Boolean | 參數為true,結果為1,參數為false,結果為+0 |
Number | 不轉換 |
String | 參見下文的文法和注釋 |
Object | 應用下步驟:1、設原始值為ToPrimitive(輸入參數,暗示,數值類型)。2、返回ToNumber(原始值) |
ToPrimitive運算符接收一個值,和一個可選的期望類型作參數。ToPrimitive運算符把其值參數轉換為非類型對象。如果對象有能力被轉換為不止一種原語類型,可以使用可選的 期望類型 來暗示那個類型。
輸入類型 | 結果 |
---|---|
Undefined | 不轉換 |
Null | 不轉換 |
Boolean | 不轉換 |
Number | 不轉換 |
String | 不轉換 |
Object | 返回該對象的默認值。對象的默認值由期望類型傳入作為hint參數調用對象內部方法[DefaultValue]得到 |
** ToPrimitive這個方法,參照火狐MDN上的文檔介紹,大致意思如下:
ToPrimitive(obj,preferredType)
JS引擎內部轉換為原始值ToPrimitive(obj,preferredType)函數接受兩個參數,第一個obj為被轉換的對象,第二個
preferredType為希望轉換成的類型(默認為空,接受的值為Number或String)在執行ToPrimitive(obj,preferredType)時如果第二個參數為空并且obj為Date的實例時,此時preferredType會
被設置為String,其他情況下preferredType都會被設置為Number如果preferredType為Number,ToPrimitive執
行過程如
下:如果obj為原始值,直接返回;
否則調用 obj.valueOf(),如果執行結果是原始值,返回之;
否則調用 obj.toString(),如果執行結果是原始值,返回之;
否則拋異常。
如果preferredType為String,將上面的第2步和第3步調換,即:
如果obj為原始值,直接返回;
否則調用 obj.toString(),如果執行結果是原始值,返回之;
否則調用 obj.valueOf(),如果執行結果是原始值,返回之;
否則拋異常
Ok,到現在,我們需要了解,toString方法和valueOf方法;
toString用來返回對象的字符串表示。
let obj = {name:"Tom"}; //"[object Object]" let obj = {}; //"[object Object]" let arr = [1,2]; //"1,2" let arr = []; //"" let str = "1"; //"1" let num = 1; //"1" let boo = true; //"true" let date = new Date(); //"date Sat Mar 24 2018 00:23:12 GMT+0800 (CST)" let nul = null; //報錯 let und; //報錯
valueOf方法返回對象的原始值,可能是字符串、數值或bool值等,看具體的對象。
let obj = {name:"Tom"}; //{name:"Tom"} let arr = [1,2]; //[1,2] let str = "1"; //"1" let num = 1; //1 let boo = true; //true let date = new Date(); //1521822331609 let nul = null; //報錯 let und; //報錯
簡單理解:原始值指的是[Null,Undefined,String,Boolean,Number]五種基本數據類型之一
總結一下==運算的規則:1. undefined == null,結果是true。且它倆與所有其他值比較的結果都是false。 2. String == Boolean,需要兩個操作數同時轉為Number。 3. String/Boolean == Number,需要String/Boolean轉為Number。 4. Object == Primitive(原始值),需要Object轉為Primitive(具體通過valueOf和toString方法)。栗子
undefined==null //true []==[] //false []==![] //true {}==!{} //false ![]=={} //false []==!{} //true [1,2]==![1] //falseundefined==null
結果為true,不用解釋了,記住就行了
[]==[]先看這兩個的類型,typeOf([])得到的是"object"
抽象相等算法1-f,引用同一類型的才算相等
返回false
[]==![]!取反運算符的優先級高于==,因此先算出![]這個得值,再去使用抽象相等算法進行比較
取反運算符會先調用方法ToBoolean,再去取反
ToBoolean([])返回的是true,因此![]應該為false
[]==![]轉換為了[]==false
根據抽象相等算法4條,則我們可以比較[]==ToNumber[false]的值,則可以得到[]==0
再根據抽象相等算法5條,比較ToPrimitive([])==0
由于[]不是Date類型,所以先得到[].valueOf()的值,為[]
再得到[].toString()的值,為""的字符串
以上7,8部可合并為一步即比較[].valueOf().toString(),得到""字符串,此時[]轉換為了原始值類型(即五種基本類型中的一種)了。
根據抽象相等算法3,則可以比較ToNumber("")==0,到這里[]==![]轉化為了0==0
返回true
{}==![]表達式右側,重復上一次的1-5步,可以得到{}==0
根據抽象相等算法5條,ToPrimitive({})==0,得到{}.valueOf().toString()得到一個字符串"[object Object]",是原始類型
根據抽象相等算法3,最后比較ToNumber("[object Object]")==0,轉變為1==0
返回false
...其余的栗子自己算一算吧
結語自己重新寫了寫一遍整理了一下思路,如果什么地方沒有講清楚,請指出;
參考:
剖析js中各種蛋疼的類型轉換
Javascript中抽象相等比較算法
等...文章
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/93661.html
摘要:在中的關系比較運算,指的是像這種大小值的關系比較。而相等比較,可區分為標準相等比較與嚴格相等比較兩大種類。 在JS中的關系比較(Relational Comparison)運算,指的是像x < y這種大小值的關系比較。 而相等比較,可區分為標準相等(standard equality)比較x == y與嚴格相等(strict equality)比較x === y兩大種類。嚴格相等比較會...
摘要:等同于等同于其他類型和布爾類型之間的比較如果是布爾類型,則返回的結果。 showImg(https://segmentfault.com/img/bVburFq?w=796&h=398); 前言 JavaScript作為一門弱類型語言,我們在每天的編寫代碼過程中,無時無刻不在應用著值類型轉換,但是很多時候我們只是在單純的寫,并不曾停下腳步去探尋過值類型轉換的內部轉換規則,最近通過閱讀你...
摘要:等同于等同于其他類型和布爾類型之間的比較如果是布爾類型,則返回的結果。 showImg(https://segmentfault.com/img/bVburFq?w=796&h=398); 前言 JavaScript作為一門弱類型語言,我們在每天的編寫代碼過程中,無時無刻不在應用著值類型轉換,但是很多時候我們只是在單純的寫,并不曾停下腳步去探尋過值類型轉換的內部轉換規則,最近通過閱讀你...
摘要:等同于等同于其他類型和布爾類型之間的比較如果是布爾類型,則返回的結果。 showImg(https://segmentfault.com/img/bVburFq?w=796&h=398); 前言 JavaScript作為一門弱類型語言,我們在每天的編寫代碼過程中,無時無刻不在應用著值類型轉換,但是很多時候我們只是在單純的寫,并不曾停下腳步去探尋過值類型轉換的內部轉換規則,最近通過閱讀你...
閱讀 1626·2021-09-02 09:55
閱讀 1092·2019-08-30 13:19
閱讀 1394·2019-08-26 13:51
閱讀 1445·2019-08-26 13:49
閱讀 2372·2019-08-26 12:13
閱讀 452·2019-08-26 11:52
閱讀 1899·2019-08-26 10:58
閱讀 3084·2019-08-26 10:19