跟我學(xué)習(xí)javascript的隱式強(qiáng)制轉(zhuǎn)換
JavaScript的數(shù)據(jù)類(lèi)型分為六種,分別為null,undefined,boolean,string,number,object。
object是引用類(lèi)型,其它的五種是基本類(lèi)型或者是原始類(lèi)型。我們可以用typeof方法打印來(lái)某個(gè)是屬于哪個(gè)類(lèi)型的。不同類(lèi)型的變量比較要先轉(zhuǎn)類(lèi)型,叫做類(lèi)型轉(zhuǎn)換,類(lèi)型轉(zhuǎn)換也叫隱式轉(zhuǎn)換。隱式轉(zhuǎn)換通常發(fā)生在運(yùn)算符加減乘除,等于,還有小于,大于等。。
typeof '11' //string typeof(11) //number '11' < 4 //false
一、基本類(lèi)型的轉(zhuǎn)換
下面先講加減乘除:
1. 字符串加數(shù)字,數(shù)字就會(huì)轉(zhuǎn)成字符串。
2. 數(shù)字減字符串,字符串轉(zhuǎn)成數(shù)字。如果字符串不是純數(shù)字就會(huì)轉(zhuǎn)成NaN。字符串減數(shù)字也一樣。兩個(gè)字符串相減也先轉(zhuǎn)成數(shù)字。
3. 乘,除,大于,小于跟減的轉(zhuǎn)換也是一樣。
//隱式轉(zhuǎn)換 + - * == / // + 10 + '20' //'2010' // - 10 - '20' //-10 10 - 'one' //NaN 10 - '100a' //NaN // * 10*'20' //200 '10'*'20' //200 // / 20/'10' //2 '20'/'10' //2 '20'/'one' //NaN
4.加法操作順序是敏感的
類(lèi)似這樣的混合表達(dá)式有時(shí)令人困惑,因?yàn)?JavaScript 對(duì)操作順序是敏感的。例如,表達(dá)式:1+2+"3"; //"33"
由于加法運(yùn)算是自左結(jié)合的(即左結(jié)合律),因此,它等同于下面的表達(dá)式:(1+2)+"3"; //"33"
與此相反,表達(dá)式:1+"2"+3; //"123"的計(jì)算結(jié)果為字符串“123”。左結(jié)合律相當(dāng)于是將表達(dá)式左側(cè)的加法運(yùn)算包裹在括號(hào)中。
5.再來(lái)看看一組 ==
1).undefined等于null
2).字符串和數(shù)字比較時(shí),字符串轉(zhuǎn)數(shù)字
3).數(shù)字為布爾比較時(shí),布爾轉(zhuǎn)數(shù)字
4).字符串和布爾比較時(shí),兩者轉(zhuǎn)數(shù)字
// == undefined == null; //true '0' == 0; //true,字符串轉(zhuǎn)數(shù)字 0 == false; //true,布爾轉(zhuǎn)數(shù)字 '0' == false; //true,兩者轉(zhuǎn)數(shù)字 null == false; //false undefined == false; //false
7個(gè)false值:false,0,-0,“”,NaN,null以及undefined,所有其他值都是truth
6、NaN,不是一個(gè)數(shù)字
NaN 是一個(gè)特殊值,說(shuō)明某些算術(shù)運(yùn)算(如求負(fù)數(shù)的平方根)的結(jié)果不是數(shù)字。方法 parseInt() 和 parseFloat() 在不能解析指定的字符串時(shí)就返回這個(gè)值。對(duì)于一些常規(guī)情況下返回有效數(shù)字的函數(shù),也可以采用這種方法,用 Number.NaN 說(shuō)明它的錯(cuò)誤情況。
Math.sqrt(-2) Math.log(-1) 0/0 parseFloat('foo')
對(duì)于很多JavaScript的初學(xué)者來(lái)說(shuō),它的第一個(gè)陷阱是調(diào)用typeof時(shí)返回結(jié)果的通常是你想不到的:
console.log(typeof NaN); // 'Number'
這情情況下,NaN并不意味著是一個(gè)數(shù)字,它的類(lèi)型是數(shù)字。明白嗎?
因?yàn)閠ypeof 返回的是字符串,有六種:“number”、”string”、”boolean”、”object”、”function”、”undefined
保持冷靜,因?yàn)橄旅孢€有很多混亂的地方。讓我們比較兩個(gè)NaN:
var x = Math.sqrt(-2); var y = Math.log(-1); console.log(x == y); // false
也許這是因?yàn)槲覀儧](méi)有使用嚴(yán)格等價(jià)(===)操作?顯然不是。
var x = Math.sqrt(-2); var y = Math.log(-1); console.log(x === y); // false
直接比較兩個(gè)NaN呢?
console.log(NaN === NaN); // false
因?yàn)橛泻芏喾椒▉?lái)表示一個(gè)非數(shù)字,所以一個(gè)非數(shù)字不會(huì)等于另一個(gè)為NaN的非數(shù)字,它還是有一定道理的。
但是當(dāng)然,解決方案現(xiàn)在已經(jīng)有了。讓我們認(rèn)識(shí)一下全局函數(shù)isNaN:
console.log(isNaN(NaN)); // true
唉,不過(guò) isNaN() 也有它自己的很多缺陷呀:
console.log(isNaN('hello')); // true console.log(isNaN(['x'])); // true console.log(isNaN({})); // true
這樣又產(chǎn)生了很多不同的解決方案。其中一個(gè)是利用 了NaN的非反射性質(zhì)(例如, 看看 Kit Cambridge 的筆記)
var My = { isNaN: function (x) { return x !== x; } }
不過(guò)幸運(yùn)的是,在即將到來(lái)的ECMAScript 6中, 有一個(gè)Number.isNaN() 方法提供可靠的NaN值檢測(cè)。
換句話(huà)說(shuō),只有在參數(shù)是真正的NaN時(shí),才會(huì)返回true
console.log(Number.isNaN(NaN)); // true console.log(Number.isNaN(Math.sqrt(-2))); // true console.log(Number.isNaN('hello')); // false console.log(Number.isNaN(['x'])); // false console.log(Number.isNaN({})); // false
二、引用類(lèi)型的轉(zhuǎn)換
基本類(lèi)型間的比較相對(duì)簡(jiǎn)單。引用類(lèi)型和基本類(lèi)型的比較就相對(duì)復(fù)雜一些,先要把引用類(lèi)型轉(zhuǎn)成基本類(lèi)型,再按上述的方法比較。
1.引用類(lèi)型轉(zhuǎn)布爾全是true。
比如空數(shù)組,只要是對(duì)象就是引用類(lèi)型,所以[]為true。引用類(lèi)型轉(zhuǎn)數(shù)字或者字符串就要用valueOf()或者toString();對(duì)象本身就繼承了valuOf()和toString(),還可以自定義valueOf()和toString()。根據(jù)不同的對(duì)象用繼承的valueOf()轉(zhuǎn)成字符串,數(shù)字或本身,而對(duì)象用toString就一定轉(zhuǎn)為字符串。一般對(duì)象默認(rèn)調(diào)用valueOf()。
1).對(duì)象轉(zhuǎn)數(shù)字時(shí),調(diào)用valueOf();
2).對(duì)象轉(zhuǎn)字符串時(shí),調(diào)用toString();
先看看下面的例子:
0 == []; // true, 0 == [].valueOf(); ---> 0 == 0; '0' == []; // false, '0' == [].toString(); ---> '0' == ''; 2 == ['2']; // true, 2 == ['2'].valueOf(); ---> 2 == '2' ---> 2 == 2; '2' == [2]; // true, '2' == [2].toString(); ---> '2' =='2'; [] == ![]; //true, [].valueOf() == !Boolean([]) -> 0 == false ---> 0 == 0;
對(duì)象轉(zhuǎn)成數(shù)字時(shí),調(diào)用valueOf(),在這之前先調(diào)用的是toString();所以我猜valueOf方法是這樣的。So上面的例子 0 == []要改成下面更合理。無(wú)論如何,[]最后是轉(zhuǎn)成0的。
var valueOf = function (){ var str = this.toString(); //先調(diào)用toString(),轉(zhuǎn)成字符串 //... } 0 == []; // true, 0 == [].valueOf(); -> 0 == '0' -> 0 == 0;
自定義的valueOf()和toString();
- 自定義的valueOf()和toString()都存在,會(huì)默認(rèn)調(diào)用valueOf();
- 如果只有toString(),則調(diào)用toString();
var a = [1]; a.valueOf = function (){ return 1;} a.toString = function (){ return '1';} a + 1; // 2, valueOf()先調(diào)用
去掉valueOf()就會(huì)調(diào)用toString()。
var a = [1]; a.valueOf = function (){ return 1;} a.toString = function (){ return '1';} a + 1; // 2, 先調(diào)用valueOf() //去掉valueOf delete a.valueOf; a + 1; // '11', 調(diào)用toString()
如果返回其它會(huì)怎么樣呢?
var a = [1]; a.valueOf = function (){return ;} a.toString = function (){return 1 ;}; 1 - a; //NaN
其它對(duì)象 調(diào)用valueOf()轉(zhuǎn)成不同的類(lèi)型:
var a = {}; a.valueOf(); //Object {} var a = []; a.valueOf(); //[] 自己本身 var a = new Date(); a.valueOf(); //1423812036234 數(shù)字 var a = new RegExp(); a.valueOf(); // /(?:)/ 正則對(duì)象
引用類(lèi)型之間的比較是內(nèi)存地址的比較,不需要進(jìn)行隱式轉(zhuǎn)換,這里不多說(shuō)。
[] == [] //false 地址不一樣
var a = [];
b = a;
b == a //true
2.顯式轉(zhuǎn)換
顯式轉(zhuǎn)換比較簡(jiǎn)單,可以直接用類(lèi)當(dāng)作方法直接轉(zhuǎn)換。
Number([]); //0
String([]); //”
Boolean([]); //true
還有更簡(jiǎn)單的轉(zhuǎn)換方法。
3 + ” // 字符串'3'
+'3' // 數(shù)字3
!!'3' // true
以上就是本文的全部?jī)?nèi)容,詳細(xì)介紹了javascript的隱式強(qiáng)制轉(zhuǎn)換,希望對(duì)大家的學(xué)習(xí)有所幫助。
- 簡(jiǎn)單介紹JavaScript數(shù)據(jù)類(lèi)型之隱式類(lèi)型轉(zhuǎn)換
- 淺析JavaScript中的隱式類(lèi)型轉(zhuǎn)換
- JavaScript隱式類(lèi)型轉(zhuǎn)換
- JavaScript中運(yùn)算符規(guī)則和隱式類(lèi)型轉(zhuǎn)換示例詳解
- 基于javascript 顯式轉(zhuǎn)換與隱式轉(zhuǎn)換(詳解)
- JavaScript中的一些隱式轉(zhuǎn)換和總結(jié)(推薦)
- JS面試題大坑之隱式類(lèi)型轉(zhuǎn)換實(shí)例代碼
- JavaScript強(qiáng)制類(lèi)型轉(zhuǎn)換和隱式類(lèi)型轉(zhuǎn)換操作示例
- 對(duì)存在JavaScript隱式類(lèi)型轉(zhuǎn)換的四種情況的總結(jié)(必看篇)
- 一篇文章讓你輕松記住js的隱式轉(zhuǎn)化
相關(guān)文章
eval(function(p,a,c,k,e,d)系列解密javascript程序
在網(wǎng)上下載源代碼時(shí),很可能發(fā)現(xiàn)代碼里的JS腳本看不懂,這是由于JS加密造成的。如果你發(fā)現(xiàn)JS是以eval(function(p,a,c,k,e,r){e=function(c)開(kāi)頭的,看到這個(gè)頁(yè)面你就可以解決他2007-04-04JavaScript性能優(yōu)化 創(chuàng)建文檔碎片(document.createDocumentFragment)
講這個(gè)方法之前,我們應(yīng)該先了解下插入節(jié)點(diǎn)時(shí)瀏覽器會(huì)做什么。2010-07-07javascript中alert()與console.log()的區(qū)別
我們?cè)谧鰆s調(diào)試的時(shí)候使用 alert 可以顯示信息,調(diào)試程序,alert 彈出窗口會(huì)中斷程序, 如果要在循環(huán)中顯示信息,手點(diǎn)擊關(guān)閉窗口都累死。而且 alert 顯示對(duì)象永遠(yuǎn)顯示為[object ]。 自己寫(xiě)的 log 雖然可以顯示一些 object 信息,但很多功能支持都沒(méi)有 console 好2015-08-08Bootstrap 實(shí)現(xiàn)表格樣式、表單布局的實(shí)例代碼
這篇文章主要介紹了Bootstrap 實(shí)現(xiàn)表格樣式、表單布局的實(shí)例代碼,需要的朋友可以參考下2018-12-12原生js實(shí)現(xiàn)shift/ctrl/alt按鍵的獲取
小測(cè)試shift、ctrl、alt按鍵的獲取,感興趣的朋友可以參考下哈,希望可以幫助到你2013-04-04JavaScript中正則表達(dá)式判斷匹配規(guī)則及常用方法
JS作為一門(mén)常用于web開(kāi)發(fā)的語(yǔ)言,必然要具備正則這種強(qiáng)大的特性,本文將對(duì)JS中的正則用法及常用函數(shù)進(jìn)行一番總結(jié)2017-08-08使用JS實(shí)現(xiàn)簡(jiǎn)易計(jì)算器
這篇文章主要為大家詳細(xì)介紹了使用JS實(shí)現(xiàn)簡(jiǎn)易計(jì)算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06