本文參考文獻:
[1] https://www.cnblogs.com/zaizaizai8/p/6516978.html javascript的typeof返回哪些數據類型
[2] https://www.cnblogs.com/chenmeng0818/p/5954215.html js的隱式轉換
1、javascript的typeof返回哪些數據類型
1.返回數據類型
undefined、string、boolean、number、symbol(ES6)、Object、Function
2.強制類型轉換
Number(參數)把任何類型轉換成數值類型;parseInt(參數1,參數2)將字符串轉換成整數;parseFloat()將字符串轉換成浮點數字;string(參數):可以將任何類型轉換成字符串
;Boolean()可以將任何類型的值轉換成布爾值
3.隱式類型轉換
(1).四則運算
加法運算符+是雙目運算符,只要其中一個是string類型,表達式的值便是一個String。
對於其他的四則運算,只要其中一個是Number類型,表達式的便是一個Number。
對於非法字符的情況通常會返回NaN:'1'*'a' // => NaN,這是因為parseInt(a)值為NaN,1*NaN還是NaN
(2).判斷語句
判斷語句中的判斷條件需要是 Boolean類型,所以條件表達式會被隱式轉換為Boolean。其轉換規則則同Boolean的構造函數。比如:
var obj = {};if(obj){while(obj);}
(3).Native代碼調用
JavaScript宿主環境都會提供大量的對象,它們往往不少通過JavaScript來實現的。JavaScript給這些函數傳入的參數也會進行隱式轉換。例如BOM提供的alert方法接受String類型的參數:alert({a:1}); //=>[object Object]
//一些比較規則 //1. 對象和布爾值比較 //對象和布爾值進行比較時,對象先轉換為字符串,然后再轉換為數字,布爾值直接轉換為數字 console.log([] == true); //false []轉換為字符串'',然后轉換為數字0,true轉換為數字1,所以為false //2. 對象和字符串比較 //對象和字符串進行比較時,對象轉換為字符串,然后兩者進行比較。 console.log([1,2,3] == '1,2,3'); // true [1,2,3]轉化為'1,2,3',然后和'1,2,3', so結果為true; //3. 對象和數字比較 //對象和數字進行比較時,對象先轉換為字符串,然后轉換為數字,再和數字進行比較。 console.log([1] == 1); // true `對象先轉換為字符串再轉換為數字,二者再比較 [1] => '1' => 1 所以結果為true //4. 字符串和數字比較 //字符串和數字進行比較時,字符串轉換成數字,二者再比較。 console.log('1' == 1) // true //5. 字符串和布爾值比較 //字符串和布爾值進行比較時,二者全部轉換成數值再比較。 console.log('1' == true); // true //6. 布爾值和數字比較 //布爾值和數字進行比較時,布爾轉換為數字,二者比較。 console.log(true == 1); // true //許多剛接觸js的童鞋看到這么多的轉換規則就懵圈了,其實規律很簡單,大家可以記下邊這個圖(是時候展現我高超的繪畫技巧了) //數據轉換 //如圖,任意兩種類型比較時,如果不是同一個類型比較的話,則按如圖方式進行相應類型轉換,如對象和布爾比較的話,對象 => 字符串 => 數值 布爾值 => 數值。 //另外,我們來看下一些需要"特別照顧"的。 //有一個比較坑的地方,之前有跟后台聯調時候拿空數組做校驗,然后發現流程走的在意料之外的 console.log([] == false); console.log(![] == false); /這兩個的結果都是true,第一個是,對象 => 字符串 => 數值0 false轉換為數字0,這個是true應該沒問題, //第二個前邊多了個!,則直接轉換為布爾值再取反,轉換為布爾值時,空字符串(''),NaN,0,null,undefined這幾個外返回的都是true, 所以! []這個[] => true 取反為false,所以[] == false為true。 //還有一些需要記住的,像: console.log(undefined == null) //true undefined和null 比較返回true,二者和其他值比較返回false console.log(Number(null)) //0
4、小拓展
(1)判斷是否為數組(typeOf 肯定不行咯,返回的是object)
instanceof
var ary = [1,2,3,4]; console.log(ary instanceof Array)//true;
原型鏈方法
var ary = [1,2,3,4]; console.log(ary.__proto__.constructor==Array);//true console.log(ary.constructor==Array)//true 這兩段代碼是一樣的
但是,instanceof 和constructor 判斷的變量,必須在當前頁面聲明的,比如,一個頁面(父頁面)有一個框架,框架中引用了一個頁面(子頁面),在子頁面中聲明了一個ary,並將其賦值給父頁面的一個變量,這時判斷該變量,Array == object.constructor;會返回false;
原因:
1、array屬於引用型數據,在傳遞過程中,僅僅是引用地址的傳遞。
2、每個頁面的Array原生對象所引用的地址是不一樣的,在子頁面聲明的array,所對應的構造函數,是子頁面的Array對象;父頁面來進行判斷,使用的Array並不等於子頁面的Array;切記,不然很難跟蹤問題!react這種組件化的框架中經常會遇到這種坑。。。
通用的方法:
var ary = [1,2,3,4];
//自己封裝一個isArray的方法,還是在原型上找比較靠譜 function isArray(o){ return Object.prototype.toString.call(o)=='[object Array]'; } console.log(isArray(ary));
Object.prototype.toString ( )(簡單說下大概原理,基於ES5規范,詳情自行Google)
在toString方法被調用時,會執行下面的操作步驟:
如果this的值為undefined,則返回"[object Undefined]".
如果this的值為null,則返回"[object Null]".
讓O成為調用ToObject(this)的結果.
讓class成為O的內部屬性[[Class]]的值.
返回三個字符串"[object ", class, "]"連接后的新字符串.
所有內置對象的[[Class]]屬性的值是由ES5規范定義的.所有宿主對象的[[Class]]屬性的值可以是除了"Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp", "String"之外的的任何字符串.[[Class]]內部屬性是引擎內部用來判斷一個對象屬於哪種類型的值的.只能通過Object.prototype.toString方法訪問
(2)判斷是否是空對象
如果對象不為空,並且知道對象不為空時,某個屬性(比如{id:111})一定存在,則可以里這樣判斷:
var d = {}; var e = {id:111}; if(d.id){ console.log(1);} if(e.id){ console.log(2);}
//9 這是效率比較高的辦法,實際工作中常用
單純判斷空對象
var c = {}; if(JSON.stringify(c) == "{}"){ console.log(3);}//3 原因上面有。。
(3)判斷是否是空數組
var a=[]; if(JSON.stringify(a) === '[]'){ console.log('a是空數組') }
或者已經知道類型一定是數組
var a=[]; if(a.length===0){ console.log('a是空數組') }