有趣的JavaScript隱式類型轉(zhuǎn)換操作實例分析
本文實例講述了JavaScript隱式類型轉(zhuǎn)換操作。分享給大家供大家參考,具體如下:
JavaScript的數(shù)據(jù)類型是非常弱的(不然不會叫它做弱類型語言了)!在使用算術(shù)運算符時,運算符兩邊的數(shù)據(jù)類型可以是任意的,比如,一個字符串可以和數(shù)字相加。之所以不同的數(shù)據(jù)類型之間可以做運算,是因為JavaScript引擎在運算之前會悄悄的把他們進行了隱式類型轉(zhuǎn)換的,如下是數(shù)值類型和布爾類型的相加:
3 + true; // 4
結(jié)果是一個數(shù)值型!如果是在C或者Java環(huán)境的話,上面的運算肯定會因為運算符兩邊的數(shù)據(jù)類型不一致而導致報錯的!但是,在JavaScript中,只有少數(shù)情況下,錯誤類型才會導致出錯,比如調(diào)用非函數(shù),或者讀取null或者undefined的屬性時,如下:
'hello'(1); // error: not a functionnull.x; // error: cannot read property ’x’ of null
多數(shù)情況下,JavaScript都不會出錯的,而是自動的進行相應的類型轉(zhuǎn)換。比如-, *, /,和%等算術(shù)運算符都會把操作數(shù)轉(zhuǎn)換成數(shù)字的,但是“+”號就有點不一樣了,有些情況下,它是算術(shù)加號,有些情況下,是字符串連接符號,具體的要看它的操作數(shù),如下:
2 + 3; // 5'hello' + ' world'; // 'hello world'
但是,如果字符串和數(shù)字相加,會是怎樣的結(jié)果呢?JavaScript會自動把數(shù)字轉(zhuǎn)換成字符的,不管數(shù)字在前還是字符串在前,如下:
'2' + 3; // '23'2 + '3'; // '23'
字符串和數(shù)字相加結(jié)果是字符串,字符串和數(shù)字相加結(jié)果是字符串,字符串和數(shù)字相加結(jié)果是字符串,重要的事情說三遍!!!!!!
此外,需要注意的是,“+”的運算方向是從左到右的,如下:
1 + 2 + '3'; // '33'
這與下面是等價的:
(1 + 2) + '3'; // '33'
相比之下,下面的結(jié)果是不一樣的:
1 + '2' + 3; // '123'
但是,隱式類型轉(zhuǎn)換,有時候,會隱藏一些錯誤的,比如,null會轉(zhuǎn)換成0,undefined會轉(zhuǎn)換成NaN。需要注意的是,NaN和NaN是不相等的(這是由于浮點數(shù)的精度決定的),如下:
var x = NaN;x === NaN; // false
雖然,JavaScript提供了isNaN來檢測某個值是否為NaN,但是,這也不太精確的,因為,在調(diào)用isNaN函數(shù)之前,本身就存在了一個隱式轉(zhuǎn)換的過程,它會把那些原本不是NaN的值轉(zhuǎn)換成NaN的,如下:
isNaN('foo'); // trueisNaN(undefined); // trueisNaN({}); // trueisNaN({ valueOf: 'foo' }); // true
上面代碼,我們使用isNaN來測試后,發(fā)現(xiàn)字符串,undefined,甚至對象,結(jié)果都返回真!!!但是,我們總不能說他們也是NaN吧?總而言之,得出的結(jié)論是:isNaN檢測NaN并不可靠!!!
幸運的是,有一種可靠的并且準確的方法可以檢測NaN。我們都知道,只有NaN是自己不等自己的,那么,我們就以使用不等于號(!==)來判斷一個數(shù)是否等于自身,從而,可以檢測到NaN了,如下:
var a = NaN;a !== a; // truevar b = 'foo';b !== b; // falsevar c = undefined;c !== c; // falsevar d = {};d !== d; // falsevar e = { valueOf: 'foo' };e !== e; // false
我們也可以把這種模式定義成一個函數(shù),如下:
function isReallyNaN(x) { return x !== x;}
OK,NaN的檢測方法就是這么簡單,我們下面繼續(xù)討論對象的隱式轉(zhuǎn)換!
對象是可以轉(zhuǎn)換成原始值的,最常見的方法就是把它轉(zhuǎn)換成字符串,如下:
'the Math object: ' + Math; // 'the Math object: [object Math]''the JSON object: ' + JSON; // 'the JSON object: [object JSON]'
對象轉(zhuǎn)換成字符串是調(diào)用了他的toSting函數(shù)的,你可以手動的調(diào)用它來檢測一下:
Math.toString(); // '[object Math]'JSON.toString(); // '[object JSON]'
類似的,對象也是可以轉(zhuǎn)換成數(shù)字的,他是通過valueOf函數(shù)的,當然,你也是可以自定義這個valueOf函數(shù)的,如下:
'J' + { toString: function() { return 'S'; } }; // 'JS'2 * { valueOf: function() { return 3; } }; // 6
如果,一個對象同時存在valueOf方法和toString方法,那么,valueOf方法總是會被優(yōu)先調(diào)用的,如下:
var obj = { toString: function() { return '[object MyObject]'; }, valueOf: function() { return 17; }};'object: ' + obj; // 'object: 17'
但是,多數(shù)情況下,這都不是我們想要的,一般的,盡可能使valueOf和toString表示的值相同(盡管類型可以不同)。
最后一種強制類型轉(zhuǎn)換,我們常常稱之為“真值運算”,比如,if, ||, &&,他們的操作數(shù)不一定是布爾型的額。JavaScript會通過簡單的轉(zhuǎn)換規(guī)則,將一些非布爾類型的值轉(zhuǎn)換成布爾型的。大多數(shù)的值都會轉(zhuǎn)換成true,只有少數(shù)的是false,他們分別是:false, 0, -0, '', NaN, null, undefined,因為存在數(shù)字和字符串以及對象的值為false,所以,直接用真值轉(zhuǎn)換來判斷一個函數(shù)的參數(shù)是否傳進來了,這是不不太安全的。比如,有一個可以具有默認值得可選參數(shù)的函數(shù),如下:
function point(x, y) {if (!x) { x = 320;}if (!y) { y = 240;} return { x: x, y: y };}
這個函數(shù)會忽略任何的真值為假的參數(shù)的,包括0,-0;
point(0, 0); // { x: 320, y: 240 }
檢測undefined的更加準確的方法是用typeof操作:
function point(x, y) {if (typeof x === 'undefined') { x = 320;}if (typeof y === 'undefined') { y = 240;} return { x: x, y: y };}
這種寫法,可以區(qū)分開0和undefined的:
point(); // { x: 320, y: 240 }point(0, 0); // { x: 0, y: 0 }
另外一種方法是利用參數(shù)跟undefined作比較,如下:
if (x === undefined) { ... }
總結(jié):
1. 類型錯誤有可能會被類型轉(zhuǎn)換所隱藏。2. “+”既可以表示字符串連接,又可以表示算術(shù)加,這取決于它的操作數(shù),如果有一個為字符串的,那么,就是字符串連接了。3. 對象通過valueOf方法,把自己轉(zhuǎn)換成數(shù)字,通過toString方法,把自己轉(zhuǎn)換成字符串。4.具有valueOf方法的對象,應該定義一個相應的toString方法,用來返回相等的數(shù)字的字符串形式。5.檢測一些未定義的變量時,應該使用typeOf或者與undefined作比較,而不應該直接用真值運算。
感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運行工具:http://tools.jb51.net/code/HtmlJsRun測試上述代碼運行效果。
更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《JavaScript數(shù)學運算用法總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript數(shù)組操作技巧總結(jié)》、《JavaScript排序算法總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》、《JavaScript查找算法技巧總結(jié)》及《JavaScript錯誤與調(diào)試技巧總結(jié)》
希望本文所述對大家JavaScript程序設計有所幫助。
相關(guān)文章:
1. React+umi+typeScript創(chuàng)建項目的過程2. ASP中常用的22個FSO文件操作函數(shù)整理3. ASP編碼必備的8條原則4. ASP調(diào)用WebService轉(zhuǎn)化成JSON數(shù)據(jù),附json.min.asp5. 三個不常見的 HTML5 實用新特性簡介6. Warning: require(): open_basedir restriction in effect,目錄配置open_basedir報錯問題分析7. SharePoint Server 2019新特性介紹8. 無線標記語言(WML)基礎之WMLScript 基礎第1/2頁9. ASP.NET Core 5.0中的Host.CreateDefaultBuilder執(zhí)行過程解析10. php測試程序運行速度和頁面執(zhí)行速度的代碼
