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