js數據類型判斷和轉換

前言

不管筆試仍是面試,總會問到數據類型和隱式轉換。今天完全整理一下這塊的知識,但願對你們有幫助。javascript

看到下面的題,是否是已經蒙了,讀完這篇文章,就能順利通關了html

console.log([] == 0) //true 

console.log(![] == 0)  //true 

console.log([] == ![]) //true

console.log([] == []) //false

console.log({} == {}) //false

console.log({} == !{}) //false

console.log([] == false) //true

console.log({} == false) //false

if([]) {console.log(3)} //3 

if([1] == [1]){console.log(4)} //沒有輸出

console.log('2' > 10) //false

console.log('2' > '10') //true

數據類型判斷

數據類型

js數據類型一共有7種,undefined、 null、 boolean 、string、 number、 object、 Symboljava

類型判斷

typeof

typeof undefined //undefined
typeof true //boolean
typeof 42 //number
typeof '42' //string
typeof { life: 42 } //object
let s = Symbol();
typeof s //symbol

//特殊狀況
typeof [1,2,3,4]// object
typeof null //object
typeof new Date()  //object
typeof function () {}  //function

由此能夠看出,typeof不能區分數組, null和對象面試

Object.prototype.toString.call

let getType=Object.prototype.toString;

getType.call(undefined) //[object Undefined]

console.log(getType.call(true)) //[object Boolean]

console.log(getType.call(42)) //[object Number]

console.log(getType.call(Symbol()))//[object Symbol]

console.log(getType.call([1,2,3,4])) //[object Array]

console.log(getType.call(null))//[object Null]

console.log(getType.call(new Date())) //[object Date]

console.log(getType.call(function () {} )) //[object Function]

instanceof

instanceof運算符返回一個布爾值,表示對象是否爲某個構造函數的實例。json

instanceof運算符的左邊是實例對象,右邊是構造函數。它會檢查右邊構建函數的原型對象(prototype),是否在左邊對象的原型鏈上。數組

new Date instanceof Date //true
[1,2,3] instanceof Array //true

instanceof運算符只能用於對象,不適用原始類型的值。函數

constructor 屬性

prototype對象有一個constructor屬性,默認指向prototype對象所在的構造函數。prototype

function P() {}
P.prototype.constructor === P // true
[1,2].constructor === Array //true
'123'.constructor === String //true

面試常問

怎麼判斷是否是數組

instanceof、constructor、Object.prototype.toString.call、Array.isArraycode

[1,2] instanceof Array //true
[1,2].constructor === Array //true
Object.prototype.toString.call([1,2]) === '[object Array]' //true
Array.isArray([1,2]) //true

如何判斷一個對象是否是空對象

轉換成json字符串判斷htm

JSON.stringify({}) == "{}"

for in 循環判斷

let isEmptyObject = function(obj) {
    for (let key in obj) {
        return false;
    }
    return true;
}
console.log(isEmptyObject(obj));//true

使用ES6的Object.keys()

Object.keys({}).length === 0

相似的數組轉化成數組

類數組和數組均可以讀寫,獲取長度,遍歷,可是類數組不能調用數組的方法,好比push等

Array.prototype.slice.call(arguments)

或者Array.from(arguments)

字符串翻轉

'abc'.split('').reverse().join('')

字符串和數組轉換

['a', 'b', 'c'].join('') //'abc'

'abc'.split('') //['a', 'b', 'c']

類型轉換

顯示類型轉換

轉成數字,Number()、parseInt()、parseFloat()

// 數值:轉換後仍是原來的值
Number(324) // 324

// 字符串:若是能夠被解析爲數值,則轉換爲相應的數值
Number('324') // 324

// 字符串:若是不能夠被解析爲數值,返回 NaN
Number('324abc') // NaN

// 空字符串轉爲0
Number('') // 0

// 布爾值:true 轉成 1,false 轉成 0
Number(true) // 1
Number(false) // 0

// undefined:轉成 NaN
Number(undefined) // NaN

// null:轉成0
Number(null) // 0

//對象轉化
Number({a: 1}) // NaN
Number({}) //NaN 

//數組
Number([1, 2, 3]) // NaN
Number([5]) // 5
Number([]) //0

Number方法參數是對象時轉換規則

第一步,調用對象自身的valueOf方法。若是返回原始類型的值,則直接對該值使用Number函數,再也不進行後續步驟。

第二步,若是valueOf方法返回的仍是對象,則改成調用對象自身的toString方法。若是toString方法返回原始類型的值,則對該值使用Number函數,再也不進行後續步驟。

第三步,若是toString方法返回的是對象,就報錯。

轉換規則示例:

var obj = {x: 1};
Number(obj) // NaN

// 等同於
if (typeof obj.valueOf() === 'object') {
  Number(obj.toString());
} else {
  Number(obj.valueOf());
}

先使用valueOf返回了對象自己,再代用toString()返回了"[object Object]"

注意:
任何涉及NaN的操做都返回NaN,NaN和任何值不相等

Boolean

除了如下值的轉換結果爲false,其餘的值所有爲true。

false, '', 0, NaN, null, undefined

String函數能夠將任意類型的值轉化成字符串

(1)原始類型值

//數值:轉爲相應的字符串。
String(123) // "123"

//字符串:轉換後仍是原來的值。
String('abc') // "abc"

//布爾值:true轉爲字符串"true",false轉爲字符串"false"。
String(true) // "true"

//undefined:轉爲字符串"undefined"。
String(undefined) // "undefined"


//null:轉爲字符串"null"。
String(null) // "null"

(2)對象

//String方法的參數若是是對象,返回一個類型字符串
String({a: 1}) // "[object Object]"


//若是是數組,返回該數組的字符串形式。
String([1, 2, 3]) // "1,2,3"

String方法背後的轉換規則,與Number方法基本相同,只是互換了valueOf方法和toString方法的執行順序。

隱式類型轉換

自動轉化爲布爾值

if條件,while,

自動轉換爲字符串

主要發生在字符串加法,一個值爲字符串,另外一個非字符串,則後者直接轉爲字符串

'5' + 1 // '51'
'5' + true // "5true"
'5' + {} // "5[object Object]"

自動轉化爲數值

除了加法運算符(+)有可能把運算子轉爲字符串,其餘運算符都會把運算子自動轉成數值。

++/--(自增自減運算符) 

+ - * / %(算術運算符) 

+ > < >= <= == != === !=== (關係運算符)
'5' - '2' // 3
'5' * '2' // 10
true - 1  // 0
false / '5' // 0

//'abc'轉爲數值爲NaN,NaN任何運算都是NaN
'abc' - 1   // NaN

//null進行Number運算轉成0
null + 1 // 1

//undefined轉爲數值時爲NaN
undefined + 1 // NaN

== 運算符

(1)原始類型的數據會轉換成數值類型再進行比較。

1 == true // true
// 等同於 1 === Number(true)

0 == false // true
// 等同於 0 === Number(false)

2 == true // false
// 等同於 2 === Number(true)


'true' == true // false
// 等同於 Number('true') === Number(true)
// 等同於 NaN === 1

'' == 0 // true
// 等同於 Number('') === 0
// 等同於 0 === 0

'' == false  // true
// 等同於 Number('') === Number(false)
// 等同於 0 === 0

'1' == true  // true
// 等同於 Number('1') === Number(true)
// 等同於 1 === 1

'\n  123  \t' == 123 // true
// 由於字符串轉爲數字時,省略前置和後置的空格

(2)對象與原始類型值比較

對象(這裏指廣義的對象,包括數組和函數)與原始類型的值比較時,對象轉化成原始類型的值,再進行比較。

[1] == 1 // true
// 等同於 Number([1]) == 1

[1] == '1' // true
// 等同於 Number([1]) == Number('1')

[1] == true // true
// 等同於 Number([1]) == Number(true)

實戰練習

//true,空數組valueOf仍是空數組,toString()轉成獲得空字符串,空字符串調用Number轉成0
console.log([] == 0) //true 

//true,非的運算級別高,空數組轉爲布爾值爲true,因此![]獲得的false,Number轉換爲0, 最後結果仍是true
console.log(![] == 0)  //true 

//true,前面是調用valueOf()後調用toString()轉成false,後邊是非轉成false
console.log([] == ![]) 


//false,2個數組放在堆裏面,棧中存儲的是地址
console.log([] == []) 

//引用類型存儲在堆中,棧中的是地址,因此是false
console.log({} == {}) 

//{}.valueOf().toString()獲得的是[object, Object], !{}獲得的是false,Number轉換後不相等
console.log({} == !{})

//數組的valueOf().toString()後爲空,因此是真
console.log([] == false) //true

//由於對象調用valueOf後爲{}, toString後轉爲[object, Object],Number後是NaN,
//任何涉及NaN的操做都返回NaN,NaN和任何值不相等
console.log({} == false) //false

//空數組的boolean值爲true
if([]) {console.log(3)} //3 

//2個數組的棧地址不一樣
if([1] == [1]){console.log(4)} //沒有輸出

//false,轉成2>10
console.log('2' > 10) 

//都是字符串,按照字符串的unicode轉換,'2'.charCodeAt() > '10'.charCodeAt = 50 > 49
console.log('2' > '10') 

//都是字符串,按照字符串的unicode轉換
console.log('abc' > 'b') //false

參考:http://javascript.ruanyifeng....

相關文章
相關標籤/搜索