你掌握了嗎?——js數據類型隱式轉換

js數據類型隱式轉換

前言

衆所周知javascript是一種弱類型語言。強類型和弱類型主要是站在變量類型處理的角度進行分類的。強類型是一旦指定數據類型,若是不通過強制轉換,那麼將永遠是指定的這個類型。js中沒法聲明數據類型,變量類型是根據實際值決定的,由編譯器自動調用轉換函數進行轉換,這種方式稱之爲隱式轉換,今天咱們就來談談數據類型是如何隱式轉換的。javascript

js數據類型

js數據類型共7種,包括6種基本數據類型,分別是Undefined、Null、String 、Number、Boolean、以及ES6新增的數據類型Symbol,一種複雜數據類型Object。前端

  • Undefined 只有一個值就是undefined,表示未經初始化的變量值
  • Null 只有一個值null,null值表示空對象指針
  • String 表示零個或多個16位的Unicode字符組成的字符序列
  • Number 包括整數和浮點數
  • Boolean 有兩個字面值:true和false,表示一個邏輯實體
  • Symbol 每次建立的值都是惟一的,不能被強制轉換
  • Object 複雜數據類型

js引擎內部實現類型轉換的4個抽象操做

隱式類型轉換是在必定場景下,js運行環境自動調用這幾個方法,嘗試轉換成指望的數據類型java

  • ToString(argument)
  • ToNumber(argument)
  • ToBoolean(argument)
  • ToPrimitive(input[ , PreferredType])

ToPrimitive(input[, PreferredType])

將input對象轉成原始類型值,依賴valueOf()和toString()數組

PreferredType參數是Number,則ToPrimitive執行順序:bash

  1. input自己是原始類型,返回input。
  2. 調用input.valueOf(),若是結果是原始類型,則返回這個結果。
  3. 調用input.toString(),若是結果是原始類型,則返回這個結果。
  4. 拋出TypeError異常。

PreferredType 參數是String,ToPrimitive執行順序:函數

  1. input自己是原始類型,返回input。
  2. 調用input.toString(),若是結果是原始類型,則返回這個結果。
  3. 調用input.valueOf(),若是結果是原始類型,則返回這個結果。
  4. 拋出TypeError異常。

PreferredType沒有傳入參數編碼

  • 若是input是內置的Date類型,PreferredType視爲String
  • 不然PreferredType視爲Number

ToBoolean(argument)

Argument Type Result
Undefined false
Null false
Boolean return argument
Number 僅當argument參數是 +0, -0, or NaN時,return false;不然return true
String 僅當argument參數是 空字符串時,return false;不然return true
Symbol true
Object true

ToNumber(argument)

Argument Type Result
Undefined NaN
Null +0
Boolean argument 爲 true, return 1; argument 爲 false, return 0
Number return argument參數
String 將字符串中的內容轉化爲數字(好比"23"->23),若是轉化失敗則返回NaN(好比"23a"->NaN)
Symbol 拋出 TypeError 異常
Object 先primValue = ToPrimitive(argument, Number),再對primValue使用ToNumber(primValue)

ToString(argument)

Argument Type Result
Undefined "undefined"
Null "null"
Boolean argument 爲 true, return "true"; argument 爲 false, return "false"
Number 用字符串表示數字
String 返回argument
Symbol 拋出 TypeError 異常
Object 先primValue = ToPrimitive(argument, Number),再對primValue使用ToString(primValue)

常見的隱式類型轉換

轉成String類型

  • 字符串鏈接符(+)轉成字符串
var a = 123
var n = a + 'helloworld';
console.log(n)   // '123hellowold'

a = true
var m = a + 'helloworld'
console.log(m)   // 'truehelloworld'
複製代碼

轉成Number型

  • 自增自減運算符 ++/--
  • 加減乘除求餘算數運算符 +-*/%
var a = '100'
var b = a--
var c = a/2
console.log(b) // 100
console.log(a) // 99
a+= ''
console.log(c) // 49.5

複製代碼
  • 關係運算符 > < >= <= == != === !===
  1. 當關系運算符一邊有字符串時,會將其數據類型使用Number轉換,再作比較;
  2. 當兩邊都是字符串時,則都轉成Number,注意:此時不是轉成對應的數字,而是按照字符串對應的的unicode編碼轉成數字
  3. 多個字符從左往右進行比較
console.log('10' > 3) // true 先轉成數字10再比較
console.log('3' > '10') // true

console.log('3'.charCodeAt()) // 51
console.log('10'.charCodeAt()) // 49

console.log('abc' > 'b') // false 先比較a和b,a和b不等,直接false
console.log('abc' > 'ade') // false,先比較aa,相等,繼續比較db,得出結果
console.log('b'.charCodeAt()) // 98
console.log('d'.charCodeAt()) // 100

複製代碼
  1. 特殊狀況,沒啥規則請記住如下結論
console.log(undefined == undefined) // true 
console.log(undefined === undefined) // true

console.log(undefined == null) // true undefined是從null派生出來的
console.log(undefined === null) // false

console.log(null == null) // true
console.log(null === null) // true

console.log(NaN == NaN) // false NaN與任何數據比較都是NaN

複製代碼

轉成Boolean型

數據在邏輯判斷和邏輯運算之中會隱式轉換爲Boolean類型spa

  • Boolean轉換參考上述ToBoolean(argument)說明, 如下這幾種數據通過Boolean轉換,會轉成false,+0、-0、NaN、undefined、null、""、document.all(); 複雜數據類型通過Boolean轉換後都是true,如:[]、{}
  • 邏輯非運算符! 邏輯非運算中,會將數據先作Boolean轉換,而後取反
var a = undefined
console.log(!a) // true 先Boolean(a) => false; 再取反 !false => true

複製代碼

進階

字符串運算符與算術運算符

轉換類型取決於,加號「+」兩邊的數據類型.net

  • 只要有一邊是字符串則將非字符串的一邊轉成字符串
console.log(123 + 'true') // '123true'
複製代碼
  • 符號兩邊有一邊是Number型,此時+爲算數運算符,則將令一邊的數據轉成Number型。此處注意空字符串、null以及布爾的false Number以後都是0
console.log(1 + true) // 2 先Number(true)=> 1,再作加計算,結果爲2
console.log(1 + undefined) // 先Number(undefined) => NaN ,再計算,結果NaN
console.log(1 + null) // 先Number(null) => 0,再計算,結果爲1

複製代碼

複雜數據類型隱式轉換

複雜數據類型隱式轉換時會先調用自身的valueOf()和toString()兩個函數,若是自身數據原型對象上沒有相應的函數則會由原型鏈__proto__最終調用到Object.prototype對象對應的函數上,全部對象(除Null 和 undefined)都會繼承這兩個方法。prototype

valueOf 返回這個對象邏輯上對應的原始類型的值,原始值是存儲在棧(stack)中的簡單數據段,原始類型就是前面說的基本數據類型。原始值是啥?請看這裏原始值;valueOf是啥? 請看這裏valueOf

toString 返回這個對象的字符串表示

  • 轉換規則如前面所述,使用valueOf()獲取原始值,若是原始值不是基本類型,則使用toString方法轉成字符串
console.log([1,2] == '1,2') // true 解析以下

console.log([1,2].valueOf()) // [1,2],獲取原始值
console.log([1,2].toString()) // '1,2',轉成字符串,與右邊數據相等

var a = {}
console.log(a == "[object Object]") // true

// 左邊轉換過程
console.log(a.valueOf()) // {}
console.log({}.toString()) // "[object Object]",再進行比較
複製代碼

邏輯非隱式轉換與關係運算符隱式轉換

  • 邏輯非優先級高於關係符運算
console.log(![] == 0) // true 解析:空數組轉換布爾型是true,取非後爲falsefalse跟數字0比較,
布爾型被Number後爲0,0 == 0

console.log([] == ![]) // true [].valueOf().toString()=>''; ![] => false 關係運算符將兩邊轉成Number型進行比較,Number('') => 0; Number(false) => 0

console.log({} == !{}) // false 邏輯非優先級高,實際上是{}和!{},這個邏輯表達式的比較,按照複雜類型隱式轉換規則,需經過valueOf和toString轉換後進行比較

複製代碼
  • 引用數據類型的轉化處理
    1. 引用數據類型,可稱爲對象類型,包括Object 、Array 、Function 、Date等;數據存在堆中,變量中存的是堆地址,咱們只能操做存在棧內存的引用地址。
    2. var聲明的通常是棧內存
    3. 6種基本數據類型的存儲方式是值類型,存在於棧中
console.log([] == []) // false 數組爲引用類型,在堆中存放的是兩份不一樣的數據,因此比較結果不相等
console.log({} == {}) // false,同理,{}爲引用類型,結果不相等

複製代碼

總結

本文主要講了如下幾點:

  • 瞭解js數據類型和定義
  • 瞭解js內部數據類型轉換操做
  • 關係運算符的轉換
  • + 號鏈接操做數時的隱式轉換規則
  • 複雜數據類型的轉換,如何轉成簡單值
  • 邏輯非和引用數據類型的特殊類型轉換

你掌握了js數據類型隱式轉換的方法了嗎

參考連接:

blog.csdn.net/itcast_cn/a… www.w3school.com.cn/js/pro_js_v… tc39.es/ecma262/

關於咱們

快狗打車前端團隊專一前端技術分享,按期推送高質量文章,歡迎關注點贊。

相關文章
相關標籤/搜索