JS中邏輯運算符中 == 的問題
坦白說,js中的==比數學中的==更有深度,不愧是被稱為“最糟糕的特效”之一。
查了大量資料,感謝前輩們。在此,為了溫故而知新,總結一下:
一.記住 == 運算的規則:
(1)undefined == null,結果是true。且它倆與所有其他值比較的結果都是false。
假如你打算把一個變量賦予對象類型的值,但是現在還沒有賦值,那麽你可以用
null
表示此時的狀態(證據之一就是typeof null
的結果是object
);相反,假如你打算把一個變量賦予原始類型的值,但是現在還沒有賦值,那麽你可以用
undefined
表示此時的狀態。
①Undefined類型和Null類型的都只有一個值,即undefined和null,都是空值,所以undefined == null的結果是true
②在強制轉換方法裏面:
轉換為數值類型:Number(mix)、parseInt(string,radix)、parseFloat(string)
轉換為字符串類型:toString(radix)、String(mix)
轉換為布爾類型:Boolean(mix)
也沒有誰能轉換成它們兩者,所以它倆與所有其他值比較的結果都是false。
(2)String == Boolean,需要兩個操作數同時轉為Number。
(3)String/Boolean == Number,需要String/Boolean轉為Number。
(2)和(3)中String、Blooean、Number三種類型是除undefined和null外的基本數據類型。
這三種兩兩比較都先轉成Number再對比結果。
而Boolean只有兩個值:true和false,轉換成Number: true-->1 false-->0
栗子如下:
//字符串與數字的對比
console.log(‘1‘ == 1); //true
//字符串與布爾值的對比
console.log(‘0‘ == false); //true
//數字與布爾值的對比
console.log(1 == true); //true
//數字與數字的對比
console.log(1 == 1); //true
//布爾值與布爾值的對比
console.log(false == false); //true
// 字符串與字符串的對比
console.log(‘1‘ == ‘1‘); //true
console.log(‘4a‘ == ‘f‘); //false
註意字符串之間的對比,如果不是純數字字符串,字符串之間的對比是根據ASCII表數值排列,如果第一個值相等,對比第二個...只要得出ASCII值,後面不必再對比。一般而言,字符串對比兩者需要一模一樣才能相等。
字符串比較特殊:
console.log(Number(null)); //0
console.log(Number(undefined)); //NaN
console.log(Number(‘‘)); //0
console.log(Number(‘ ‘)); //0
console.log(Number(0)); //0
console.log(Number(‘頭好暈‘)); //NaN
console.log(Number(‘0.0‘)); //0
console.log(Number(‘100px‘)); //NaN
console.log(Number(‘-10‘)); //-10
//規律:Number() 只支持數字字符串,除了空字符串,空格字符串;
(4)Object == Primitive,需要Object轉為Primitive(具體通過valueOf()和toString()方法)。
toString()方法用來得到對象的一段文字描述;而valueOf()方法用來得到對象的特征值。
顧名思義,toString()方法傾向於返回一個字符串。valueOf()方法根據規範中的描述,它傾向於返回一個數字——盡管內置類型中,valueOf()方法返回數字的只有Number和Date。
下表列出了對象的valueOf()的返回值:
對象 | 返回值 |
---|---|
Array | 數組的元素被轉換為字符串,這些字符串由逗號分隔,連接在一起。其操作與 Array.toString 和 Array.join 方法相同。 |
Boolean | Boolean 值。 |
Date | 存儲的時間是從 1970 年 1 月 1 日午夜開始計的毫秒數 UTC。 |
Function | 函數本身。 |
Number | 數字值。 |
Object | 對象本身。這是默認情況。 |
String | 字符串值。 |
-
toString(radix)方法。除undefined和null之外的所有類型的值都具有toString()方法,其作用是返回對象的字符串表示。
對象 | 操作 |
---|---|
Array | 將 Array 的元素轉換為字符串。結果字符串由逗號分隔,且連接起來。 |
Boolean | 如果 Boolean 值是 true,則返回 “true”。否則,返回 “false”。 |
Date | 返回日期的文字表示法。 |
Error | 返回一個包含相關錯誤信息的字符串。 |
Function | 返回如下格式的字符串,其中 functionname 是被調用 toString 方法函數的名稱:function functionname( ) { [native code] } |
Number | 返回數字的文字表示。 |
String | 返回 String 對象的值。 |
默認 | 返回 “[object objectname]”,其中 objectname 是對象類型的名稱。 |
當一個對象與一個非對象比較時,需要將對象轉化為原始類型,布爾類型變成數字類型。
舉個栗子:console.log([‘‘] == false); //true
(1) 首先,兩個操作數分別是對象類型、布爾類型。需要將布爾類型轉為數字類型,而false轉為數字的結果是0,所以表達式變為:[‘‘] == 0 ,兩個操作數變成了對象類型、數字類型。
(2) 需要將對象類型轉為原始類型:
首先調用[].valueOf(),由於數組的valueOf()方法返回自身,所以結果不是原始類型,繼續調用[].toString()。
對於數組來說,toString()方法的算法,是將每個元素都轉為字符串類型,然後用逗號,依次連接起來,所以最終結果是空字符串‘‘,它是一個原始類型的值。
此時,表達式變為:‘‘ == 0 ,兩個操作數變成了字符串類型、數字類型。
(3) 需要將字符串類型轉為數字類型,前面說了空字符串變成數字是0。於是表達式變為:0 == 0
結果明顯是true。
再舉個栗子:console.log({} == false);//false
console.log({}.valueOf());//{}
console.log({}.toString());//‘[object Object]‘‘
console.log({} == false);//false
二.補充:
1.JS中如何確定六大數據類型?
(1)以原始類型和復雜類型而言:
原始類型(Primitive)包括:Undefined、Null、Boolean、Number和String五種原始類型、對象類型(Object)。
(2)以typeof獲得類型:Undefined、Function、Boolean、Number、String和Object。
2.js中基本數據類型和引用數據類型的區別?
JS基本數據類型的變量存放的是基本類型數據的實際值;而引用數據類型的變量保存對它的引用,即指針。
(1)JS基本數據類型:null、undefined、number、boolean、string比較特殊
(2)引用數據類型:function object array
如:
var a = 11;
var b = a;
b = 12;
console.log(a); //11==> a的值不會隨b值得改變而改變
var c = [1,2,3];
var d = a;
c[0] = 2;
console.log(d[0]) //2==> b的值隨著a的值改變而改,因為他們指向同一個內存地址
3.強制轉換:
Number(mix)函數,可以將任意類型的參數mix轉換為數值類型。其規則為:
(1)如果是布爾值,true和false分別被轉換為1和0
(2)如果是數字值,返回本身。
(3)如果是null,返回0.
(4)如果是undefined,返回NaN。
(5)如果是字符串,遵循以下規則:
1、如果字符串中只包含數字,則將其轉換為十進制(忽略前導0)
2、如果字符串中包含有效的浮點格式,將其轉換為浮點數值(忽略前導0)
3、如果是空字符串,將其轉換為0
4、如果字符串中包含非以上格式,則將其轉換為NaN
(6)如果是對象,則調用對象的valueOf()方法,然後依據前面的規則轉換返回的值。如果轉換的結果是NaN,則調用對象的toString()方法,再次依照前面的規則轉換返回的字符串值。
parseInt(string, radix)函數,將字符串轉換為整數類型的數值。它也有一定的規則:
(1)忽略字符串前面的空格,直至找到第一個非空字符
(2)如果第一個字符不是數字符號或者負號,返回NaN
(3)如果第一個字符是數字,則繼續解析直至字符串解析完畢或者遇到一個非數字符號為止
(4)如果上步解析的結果以0開頭,則將其當作八進制來解析;如果以x開頭,則將其當作十六進制來解析
(5)如果指定radix參數,則以radix為基數進行解析
parseFloat(string)函數,將字符串轉換為浮點數類型的數值。
它的規則與parseInt基本相同,但也有點區別:字符串中第一個小數點符號是有效的,另外parseFloat會忽略所有前導0,如果字符串包含一個可解析為整數的數,則返回整數值而不是浮點數值。
String(mix)函數,將任何類型的值轉換為字符串,其規則為:
(1)如果有toString()方法,則調用該方法(不傳遞radix參數)並返回結果
(2)如果是null,返回”null”
(3)如果是undefined,返回”undefined”
Boolean(mix)函數,將任何類型的值轉換為布爾值:
以下值會被轉換為false:
false、”"、0、NaN、null、undefined,
其余任何值都會被轉換為true。
原文參考以下兩位大大:
https://www.cnblogs.com/yangyang63963/p/5916396.html
https://www.cnblogs.com/Juphy/p/7085197.html
若有錯誤,歡迎斧正!!!
JS中邏輯運算符中 == 的問題