摘要:來看代碼上面的代碼不難理解變量是通過構造函數創建的對象,變量就是一個很簡單的數值。一開始,因為是通過構造函數創建的對象,所以值為然后每一次在執行的時候,會調用一次的方法。
廢話不多說,我們先來看第一個例子吧。
某天,我遇到了這樣一個問題:給出變量a和b的定義,使下面三個語句的輸出結果都為true。
console.log(ab);
看到題目的我第一反應是懵逼的,還有這樣的操作???然后一開始的思路是往各種神奇的值上面找,比如undefined,null,NaN,“”這樣的值,自然是沒有得到想要的結果了。
但事實上,真的存在。來看代碼:
function A(){ this.a = 1; } A.prototype = { toString: function(){ return this.a += 2; } } var a = new A(); var b = 5; console.log(a < b); console.log(a == b); console.log(a > b);
上面的代碼不難理解:變量a是通過構造函數A創建的對象,變量b就是一個很簡單的數值。一開始,因為a是通過構造函數A創建的對象,所以值為1.然后每一次在執行 console.log()的時候,會調用一次A的toString方法。所以,在第一個console.log()的時候,a的值變成了3,而b的值是5,所以a為true;第二個console.log()的時候,a的值變成了5,而b的值還是5,所以a=b為true;第三個console.log()的時候,a的值變成了7,而b的值依舊是5,所以a>b為true。
經過上面的分析,我們似乎打開了一個新世界的大門,這里涉及到一個比較重要的概念:隱式類型轉換。在上面的例子里,a和b是兩個完全不一樣的類型,但是它們進行了比較,還得出了結果,這就說明有一個類型在比較的過程中轉換成了另一個類型。
這里需要提到一些規范來幫助我們更好的理解。
(小于大于的比較規則和相等是一樣的。)
對于字符串和數字來說,ES5規范11.9.3.4.5這樣規定:
(1)如果Type(x)是數字,Type(y)是字符串,則返回x == ToNumber(y)的結果
(2)如果Type(x)是字符串,Type(y)是數字,則返回ToNumber(x) == y的結果
對于其他類型和布爾類型的比較,規范11.9.3.6.7這樣規定:
(1)如果Type(x)是布爾類型,則返回ToNumber(x) == y的結果
(2)如果Type(y)是布爾類型,則返回x == ToNumber(y)的結果
對于null和undefined來說,ES5規范11.9.3.2.3這樣規定:
(1)如果x為null,y為undefined,則結果為x == y
(2)如果x為undefined,y為null,則結果為x == y
也就是說,null和undefined是相等的。
對于對象和非對象來說,ES5規范11.9.3.8.9這樣規定:
(1)如果Type(x)是字符串或數字,Type(y)是對象,則返回x == ToPrimitive(y)的結果
(2)如果Type(x)是對象,Type(y)是字符串或數字,則返回ToPrimitive(x) == y的結果
基本就是上面這幾種常見的類型的比較了。然后出現了一個我們好像不太常見的東西:ToPrimitive()這個方法。我們來簡單了解一下:
對象(或者數組)再進行比較或者類型轉換的時候,先會被轉換為相應的基本類型值,然后再根據需要進行轉換。再轉換為基本類型值的時候,抽象操作ToPrimitive會先檢查該值是否擁有valueOf()方法。如果有且返回基本類型值,就使用該值作為基本類型值,如果沒有就使用toString()方法的返回值作為基本類型值。
上面例子中的相等操作我們使用了==,而不是===。對于這二者的區別,我們經常聽到的是,==是不嚴格相等,只要值相等即可,而===是嚴格相等,必須值和類型都相等才可以。對于==來說,類型不重要,也就是說在這個過程中是包含了類型轉換的。所以,在YouDontKnowJS這本書中,給出的正確解釋是:
==允許在相等比較總進行強制類型轉換,而===不允許。
然后我們再來看第二個例子吧
題目是這樣的:[1]+[2]-[3]=?
這次打算先分析再給出答案,順便大家也可以自己想想結果是什么。
首先我們看到加減運算符左右兩邊的值都是數組,那前面提到過對于數組的處理。因為數組的valueOf()操作無法得到簡單的基本類型值,所以會調用toString(),這樣的話上面那個式子就變成了"1"+"2"-"3"=?。現在這個式子相信大家都比較熟悉了,不過不知道會不會有人一時頭腦發熱,把答案想成了0。
然后我們繼續往下,因為是加減操作符,所以我們從左至右開始計算,"1"+"2"這個結果到底是3還是12呢。那就記住簡單的一句話:如果有一個值是字符串,那么就進行字符串拼接,否則進行數字加法。那么很明顯,這里是2個字符串,進行字符串拼接,得到"12"。
好了,到目前為止,式子已經變成了"12"-"3"了,這應該已經很明顯了吧,字符串拼接是肯定不可能的,那就是進行數字運算了,那就是最簡單的12-3了,所以最終結果就是9。
其實這個例子里的通過加減運算符進行隱式類型轉換在我們日常代碼中經常出現,只是可能大家沒有特別關注,比如a + ""是把a轉換為字符串;a - 0是把a轉換為數字。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/107690.html
摘要:與此相對,強類型語言的類型之間不一定有隱式轉換。三為什么是弱類型弱類型相對于強類型來說類型檢查更不嚴格,比如說允許變量類型的隱式轉換,允許強制類型轉換等等。在中,加性運算符有大量的特殊行為。 從++[[]][+[]]+[+[]]==10?深入淺出弱類型JS的隱式轉換 本文純屬原創? 如有雷同? 純屬抄襲? 不甚榮幸! 歡迎轉載! 原文收錄在【我的GitHub博客】,覺得本文寫的不算爛的...
摘要:雖然你可能很驚訝甚至可能懷疑是的但是這都是有語言自己的一個隱式類型轉換的套路。基本的隱式類型轉換基本類型的隱式轉換這個其實我們使用的最多例如結果返回的是而不是這就是類型的隱式轉換。 基本上所有的語言都有 隱式類型轉換 ,但是對于 弱類型語言(JS) 來說 ,隱式類型轉換會比 強類型語言(Java) 帶來更大的副作用,有些行為甚至是不可思議的。雖然你可能很驚訝 ,甚至可能懷疑是 JS 的...
摘要:看下面的代碼和會對操作數執行條件判斷,如果操作數不是布爾值,會先執行類型轉換后再執行條件判斷。大家記住這個規則布爾值如果與其他類型進行抽象比較,會先用將布爾值轉換為數字再比較。 在上一篇中我們聊過了 JS 類型轉換的規則和我發現的一些常見書籍中關于類型轉換的一些小錯誤,當碰到顯示類型轉換的時候大家可以按照這些規則去拆解出答案。但 JS 中存在一些很隱晦的隱式類型轉換,這一篇就來談下我對...
摘要:說明在比較的時候,會進行隱式轉換,你如果對隱式轉換不是特別熟悉,結果往往出乎你的意料。解釋相信我,這行代碼是簡單的,它并不復雜,我們先來分解一下這行代碼我們把這一行,分解成了行了。簡單說中的與方法簡單說與引發的思考 說明 JavaScript在比較的時候,會進行隱式轉換,你如果對隱式轉換不是特別熟悉,結果往往出乎你的意料。 我們來看看這行代碼 (![]+[])[+!![]- -+!!...
摘要:說明在比較的時候,會進行隱式轉換,你如果對隱式轉換不是特別熟悉,結果往往出乎你的意料。解釋相信我,這行代碼是簡單的,它并不復雜,我們先來分解一下這行代碼我們把這一行,分解成了行了。簡單說中的與方法簡單說與引發的思考 說明 JavaScript在比較的時候,會進行隱式轉換,你如果對隱式轉換不是特別熟悉,結果往往出乎你的意料。 我們來看看這行代碼 (![]+[])[+!![]- -+!!...
閱讀 2169·2023-04-25 15:00
閱讀 2343·2021-11-18 13:14
閱讀 1154·2021-11-15 11:37
閱讀 3083·2021-09-24 13:55
閱讀 1221·2019-08-30 15:52
閱讀 2644·2019-08-29 12:35
閱讀 3359·2019-08-29 11:04
閱讀 1209·2019-08-26 12:13