国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

深入js隱式類型轉換

tomato / 1951人閱讀

摘要:結合實際中的情況來看,有意或無意中涉及到隱式類型轉換的情況還是很多的。此外當進行某些操作時,變量可以進行類型轉換,我們主動進行的就是顯式類型轉換,另一種就是隱式類型轉換了。

前言

相信剛開始了解js的時候,都會遇到 2 =="2",但 1+2 == 1+"2"為false的情況。這時候應該會是一臉懵逼的狀態,不得不感慨js弱類型的靈活讓人發指,隱式類型轉換就是這么猝不及防。結合實際中的情況來看,有意或無意中涉及到隱式類型轉換的情況還是很多的。既然要用到,就需要掌握其原理,知其然重要知其所以然更重要。

js的變量類型

JavaScript 是弱類型語言,意味著JavaScript 變量沒有預先確定的類型。
并且變量的類型是其值的類型。也就是說變量當前的類型由其值所決定,夸張點說上一秒種的string,下一秒可能就是個array了。此外當進行某些操作時,變量可以進行類型轉換,我們主動進行的就是顯式類型轉換,另一種就是隱式類型轉換了。例如:

var a = "1";   
typeof a;//string 

a =parseInt(a); //顯示轉換為number
typeof a  //number   

a == "1" //true

弱類型的特性在給我們帶來便利的同時,也會給我們帶來困擾。趨利避害,充分利用該特性的前提就是掌握類型轉換的原理,下面一起看一下。

js數據類型

老生常談的兩大類數據類型:

原始類型
Undefined、 Null、 String、 Number、 Boolean

引用類型
object

此外還有一個es6新增的Symbol,先不討論它。對于這五類原始類型,突然提問可能想不全,沒必要去死記硬背,可以想一下為否的常見變量及其對應值即可。

0 Number
"" String
false Boolean
null Null
undefined Undefined

對于不同的數據格式轉換規則是不同的,我們需要分別對待。

轉換規則

既然是規范定義的規則,那就不要問為什么了,先大致看一下,爭取記住。是在不行經常翻翻看看大佬的博客es5規范。轉換有下面這么幾類,我們分別看一下具體規范。(這部分轉換規則,完全可以跳過去,看到下面的實例再回頭看應該更容易接受一些)

轉換為原始值

轉換為數字

轉換為字符串

ToPrimitive(轉換為原始值)

ToPrimitive 運算符接受一個值,和一個可選的 期望類型 作參數。ToPrimitive 運算符把其值參數轉換為非對象類型。如果對象有能力被轉換為不止一種原語類型,可以使用可選的 期望類型 來暗示那個類型。根據下表完成轉換

這段定義看起來有點枯燥。轉換為原始值,其實就是針對引用數據的,其目的是轉換為非對象類型。
如果已經是原始類型,當然就不做處理了
對于object,返回對應的原始類型,該原始類型是由期望類型決定的,期望類型其實就是我們傳遞的type。直接看下面比較清楚。
ToPrimitive方法大概長這么個樣子具體如下。

/**
* @obj 需要轉換的對象
* @type 期望轉換為的原始數據類型,可選
*/
ToPrimitive(obj,type)

type可以為number或者string,兩者的執行順序有一些差別
string:

調用obj的toString方法,如果為原始值,則返回,否則下一步

調用obj的valueOf方法,后續同上

拋出TypeError 異常

number:

調用obj的valueOf方法,如果為原始值,則返回,否則下一步

調用obj的toString方法,后續同上

拋出TypeError 異常

其實就是調用方法先后,畢竟期望數據類型不同,如果是string當然優先調用toString。反之亦然。
當然type參數可以為空,這時候type的默認值會按照下面的規則設置

該對象為Date,則type被設置為String

否則,type被設置為Number

對于Date數據類型,我們更多期望獲得的是其轉為時間后的字符串,而非毫秒值,如果為number,則會取到對應的毫秒值,顯然字符串使用更多。
其他類型對象按照取值的類型操作即可。

概括而言,ToPrimitive轉成何種原始類型,取決于type,type參數可選,若指定,則按照指定類型轉換,若不指定,默認根據實用情況分兩種情況,Date為string,其余對象為number。那么什么時候會指定type類型呢,那就要看下面兩種轉換方式了。

toNumber

某些特定情況下需要用到ToNumber方法來轉成number
運算符根據下表將其參數轉換為數值類型的值

對于string類型,情況比較多,只要掌握常見的就行了。和直接調用Number(str)的結果一致,這里就不多提了,主要是太多提不完。
需要注意的是,這里調用ToPrimitive的時候,type就指定為number了。下面的toString則為string。

toString

ToString 運算符根據下表將其參數轉換為字符串類型的值:
其實了解也很簡單,畢竟是個規范,借用大佬一張圖:

雖然是需要死記的東西,還是有些規律可循的。
對于原始值:

Undefined,null,boolean
直接加上引號,例如"null"

number 則有比較長的規范,畢竟范圍比較大
常見的就是 "1" NaN則為"NaN" 基本等同于上面一條
對于負數,則返回-+字符串 例如 "-2" 其他的先不考慮了。

對象則是先轉為原始值,再按照上面的步驟進行處理。

valueOf

當調用 valueOf 方法,采用如下步驟:

調用ToObject方法得到一個對象O

原始數據類型轉換為對應的內置對象, 引用類型則不變

調用該對象(O)內置valueOf方法.

不同內置對象的valueOf實現:

String => 返回字符串值

Number => 返回數字值

Date => 返回一個數字,即時間值,字符串中內容是依賴于具體實現的

Boolean => 返回Boolean的this值

Object => 返回this

對照代碼更清晰一點

var str = new String("123")
//123
console.log(str.valueOf())
var num = new Number(123)
//123
console.log(num.valueOf())
var date = new Date()
//1526990889729
console.log(date.valueOf())
var bool = new Boolean("123")
//true
console.log(bool.valueOf())
var obj = new Object({valueOf:()=>{
    return 1
}})
//依賴于內部實現
console.log(obj.valueOf())
運算隱式轉換

前面提了那么多抽象概念,就是為了這里來理解具體轉換的。
對于+運算來說,規則如下:

+號左右分別進行取值,進行ToPrimitive()操作

分別獲取左右轉換之后的值,如果存在String,則對其進行ToString處理后進行拼接操作。

其他的都進行ToNumber處理

在轉換時ToPrimitive,除去Date為string外都按照ToPrimitive type為Number進行處理

說的自己都迷糊了快,一起結合代碼來看一下

1+"2"+false

左邊取原始值,依舊是Number

中間為String,則都進行toString操作

左邊轉換按照toString的規則,返回"1"

得到結果temp值"12"

右邊布爾值和temp同樣進行1步驟

temp為string,則布爾值也轉為string"false"

拼接兩者 得到最后結果 "12false"

我們看一個復雜的

var obj1 = {
    valueOf:function(){
        return 1
    }
}
var obj2 = {
    toString:function(){
        return "a"
    }
}
//2
console.log(1+obj1)
//1a
console.log("1"+ obj2)
//1a
console.log(obj1+obj2)

不管多復雜,按照上面的順序來吧。

1+obj1

左邊就不說了,number

右邊obj轉為基礎類型,按照type為number進行

先調用valueOf() 得到結果為1

兩遍都是number,則進行相加得到2

1+obj2

左邊為number

右邊同樣按照按照type為number進行轉化

調用obj2.valueOf()得到的不是原始值

調用toString() return "a"

依據第二條規則,存在string,則都轉換為string進行拼接

得到結果1a

obj1+obj2

兩邊都是引用,進行轉換 ToPrimitive 默認type為number

obj1.valueOf()為1 直接返回

obj2.valueOf()得到的不是原始值

調用toString() return "a"

依據第二條規則,存在string,則都轉換為string進行拼接

得到結果1a

到這里相信大家對+這種運算的類型轉換了解的差不多了。下面就看一下另一種隱式類型轉換

== 抽象相等比較

這種比較分為兩大類,

類型相同

類型不同

相同的就不說了,隱式轉換發生在不同類型之間。規律比較復雜,規范比較長,這里也不列舉了,大家可以查看抽象相等算法。簡單總結一句,相等比較就不想+運算那樣string優先了,是以number優先級為最高。概括而言就是,都盡量轉成number來進行處理,這樣也可以理解,畢竟比較還是期望比較數值。那么規則大概如下:
對于x == y

如果x,y均為number,直接比較

 沒什么可解釋的了
 1 == 2 //false

如果存在對象,ToPrimitive() type為number進行轉換,再進行后面比較

var obj1 = {
    valueOf:function(){
        return "1"
    }
}
1 == obj2  //true
//obj1轉為原始值,調用obj1.valueOf()
//返回原始值"1"
//"1"toNumber得到 1 然后比較 1 == 1
[] == ![] //true
//[]作為對象ToPrimitive得到 ""  
//![]作為boolean轉換得到0 
//"" == 0 
//轉換為 0==0 //true

存在boolean,按照ToNumber將boolean轉換為1或者0,再進行后面比較

//boolean 先轉成number,按照上面的規則得到1  
//3 == 1 false
//0 == 0 true
3 == true // false
"0" == false //true 

如果x為string,y為number,x轉成number進行比較

//"0" toNumber()得到 0  
//0 == 0 true
"0" == 0 //true 

結束語 參考文章

ECMAScript5.1中文版 + ECMAScript3 + ECMAScript(合集)
你所忽略的js隱式轉換
這篇文章的本意是為自己解惑,寫到后面真的感覺比較乏味,畢竟規范性的東西多一點,不過深入了解一下總好過死記硬背。原文請移步我的博客。對于有些觀點說這些屬于js糟粕,完全不應該深入,怎么說呢,結合自己情況判斷吧。本人水平有限,拋磚引玉共同學習。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/95189.html

相關文章

  • 從 ++[[]][+[]]+[+[]]==10? 深入淺出弱類型 JS隱式轉換

    摘要:與此相對,強類型語言的類型之間不一定有隱式轉換。三為什么是弱類型弱類型相對于強類型來說類型檢查更不嚴格,比如說允許變量類型的隱式轉換,允許強制類型轉換等等。在中,加性運算符有大量的特殊行為。 從++[[]][+[]]+[+[]]==10?深入淺出弱類型JS的隱式轉換 本文純屬原創? 如有雷同? 純屬抄襲? 不甚榮幸! 歡迎轉載! 原文收錄在【我的GitHub博客】,覺得本文寫的不算爛的...

    miya 評論0 收藏0
  • 17道面試題徹底理解 JavaScript 中的類型轉換

    摘要:隱式類型轉換通常在邏輯判斷或者有邏輯運算符時被觸發。一元加號執行字符串的類型轉換。邏輯運算符和將值轉為型,但是會返回原始值不是。計算從表達式開始,該表達式通過方法轉換為空字符串,然后轉換為。總結查看原文關注每日一道面試題詳解 類型轉換是將值從一種類型轉換為另一種類型的過程(比如字符串轉數字,對象轉布爾值等)。任何類型不論是原始類型還是對象類型都可以進行類型轉換,JavaScript 的...

    SKYZACK 評論0 收藏0
  • 深入理解JavaScript的類型轉換

    摘要:等同于等同于其他類型和布爾類型之間的比較如果是布爾類型,則返回的結果。 showImg(https://segmentfault.com/img/bVburFq?w=796&h=398); 前言 JavaScript作為一門弱類型語言,我們在每天的編寫代碼過程中,無時無刻不在應用著值類型轉換,但是很多時候我們只是在單純的寫,并不曾停下腳步去探尋過值類型轉換的內部轉換規則,最近通過閱讀你...

    W4n9Hu1 評論0 收藏0
  • 深入理解JavaScript的類型轉換

    摘要:等同于等同于其他類型和布爾類型之間的比較如果是布爾類型,則返回的結果。 showImg(https://segmentfault.com/img/bVburFq?w=796&h=398); 前言 JavaScript作為一門弱類型語言,我們在每天的編寫代碼過程中,無時無刻不在應用著值類型轉換,但是很多時候我們只是在單純的寫,并不曾停下腳步去探尋過值類型轉換的內部轉換規則,最近通過閱讀你...

    niuxiaowei111 評論0 收藏0
  • 深入理解JavaScript的類型轉換

    摘要:等同于等同于其他類型和布爾類型之間的比較如果是布爾類型,則返回的結果。 showImg(https://segmentfault.com/img/bVburFq?w=796&h=398); 前言 JavaScript作為一門弱類型語言,我們在每天的編寫代碼過程中,無時無刻不在應用著值類型轉換,但是很多時候我們只是在單純的寫,并不曾停下腳步去探尋過值類型轉換的內部轉換規則,最近通過閱讀你...

    shuibo 評論0 收藏0

發表評論

0條評論

tomato

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<