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

資訊專(zhuān)欄INFORMATION COLUMN

深入js隱式類(lèi)型轉(zhuǎn)換

tomato / 1955人閱讀

摘要:結(jié)合實(shí)際中的情況來(lái)看,有意或無(wú)意中涉及到隱式類(lèi)型轉(zhuǎn)換的情況還是很多的。此外當(dāng)進(jìn)行某些操作時(shí),變量可以進(jìn)行類(lèi)型轉(zhuǎn)換,我們主動(dòng)進(jìn)行的就是顯式類(lèi)型轉(zhuǎn)換,另一種就是隱式類(lèi)型轉(zhuǎn)換了。

前言

相信剛開(kāi)始了解js的時(shí)候,都會(huì)遇到 2 =="2",但 1+2 == 1+"2"為false的情況。這時(shí)候應(yīng)該會(huì)是一臉懵逼的狀態(tài),不得不感慨js弱類(lèi)型的靈活讓人發(fā)指,隱式類(lèi)型轉(zhuǎn)換就是這么猝不及防。結(jié)合實(shí)際中的情況來(lái)看,有意或無(wú)意中涉及到隱式類(lèi)型轉(zhuǎn)換的情況還是很多的。既然要用到,就需要掌握其原理,知其然重要知其所以然更重要。

js的變量類(lèi)型

JavaScript 是弱類(lèi)型語(yǔ)言,意味著JavaScript 變量沒(méi)有預(yù)先確定的類(lèi)型。
并且變量的類(lèi)型是其值的類(lèi)型。也就是說(shuō)變量當(dāng)前的類(lèi)型由其值所決定,夸張點(diǎn)說(shuō)上一秒種的string,下一秒可能就是個(gè)array了。此外當(dāng)進(jìn)行某些操作時(shí),變量可以進(jìn)行類(lèi)型轉(zhuǎn)換,我們主動(dòng)進(jìn)行的就是顯式類(lèi)型轉(zhuǎn)換,另一種就是隱式類(lèi)型轉(zhuǎn)換了。例如:

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

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

a == "1" //true

弱類(lèi)型的特性在給我們帶來(lái)便利的同時(shí),也會(huì)給我們帶來(lái)困擾。趨利避害,充分利用該特性的前提就是掌握類(lèi)型轉(zhuǎn)換的原理,下面一起看一下。

js數(shù)據(jù)類(lèi)型

老生常談的兩大類(lèi)數(shù)據(jù)類(lèi)型:

原始類(lèi)型
Undefined、 Null、 String、 Number、 Boolean

引用類(lèi)型
object

此外還有一個(gè)es6新增的Symbol,先不討論它。對(duì)于這五類(lèi)原始類(lèi)型,突然提問(wèn)可能想不全,沒(méi)必要去死記硬背,可以想一下為否的常見(jiàn)變量及其對(duì)應(yīng)值即可。

0 Number
"" String
false Boolean
null Null
undefined Undefined

對(duì)于不同的數(shù)據(jù)格式轉(zhuǎn)換規(guī)則是不同的,我們需要分別對(duì)待。

轉(zhuǎn)換規(guī)則

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

轉(zhuǎn)換為原始值

轉(zhuǎn)換為數(shù)字

轉(zhuǎn)換為字符串

ToPrimitive(轉(zhuǎn)換為原始值)

ToPrimitive 運(yùn)算符接受一個(gè)值,和一個(gè)可選的 期望類(lèi)型 作參數(shù)。ToPrimitive 運(yùn)算符把其值參數(shù)轉(zhuǎn)換為非對(duì)象類(lèi)型。如果對(duì)象有能力被轉(zhuǎn)換為不止一種原語(yǔ)類(lèi)型,可以使用可選的 期望類(lèi)型 來(lái)暗示那個(gè)類(lèi)型。根據(jù)下表完成轉(zhuǎn)換

這段定義看起來(lái)有點(diǎn)枯燥。轉(zhuǎn)換為原始值,其實(shí)就是針對(duì)引用數(shù)據(jù)的,其目的是轉(zhuǎn)換為非對(duì)象類(lèi)型。
如果已經(jīng)是原始類(lèi)型,當(dāng)然就不做處理了
對(duì)于object,返回對(duì)應(yīng)的原始類(lèi)型,該原始類(lèi)型是由期望類(lèi)型決定的,期望類(lèi)型其實(shí)就是我們傳遞的type。直接看下面比較清楚。
ToPrimitive方法大概長(zhǎng)這么個(gè)樣子具體如下。

/**
* @obj 需要轉(zhuǎn)換的對(duì)象
* @type 期望轉(zhuǎn)換為的原始數(shù)據(jù)類(lèi)型,可選
*/
ToPrimitive(obj,type)

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

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

調(diào)用obj的valueOf方法,后續(xù)同上

拋出TypeError 異常

number:

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

調(diào)用obj的toString方法,后續(xù)同上

拋出TypeError 異常

其實(shí)就是調(diào)用方法先后,畢竟期望數(shù)據(jù)類(lèi)型不同,如果是string當(dāng)然優(yōu)先調(diào)用toString。反之亦然。
當(dāng)然type參數(shù)可以為空,這時(shí)候type的默認(rèn)值會(huì)按照下面的規(guī)則設(shè)置

該對(duì)象為Date,則type被設(shè)置為String

否則,type被設(shè)置為Number

對(duì)于Date數(shù)據(jù)類(lèi)型,我們更多期望獲得的是其轉(zhuǎn)為時(shí)間后的字符串,而非毫秒值,如果為number,則會(huì)取到對(duì)應(yīng)的毫秒值,顯然字符串使用更多。
其他類(lèi)型對(duì)象按照取值的類(lèi)型操作即可。

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

toNumber

某些特定情況下需要用到ToNumber方法來(lái)轉(zhuǎn)成number
運(yùn)算符根據(jù)下表將其參數(shù)轉(zhuǎn)換為數(shù)值類(lèi)型的值

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

toString

ToString 運(yùn)算符根據(jù)下表將其參數(shù)轉(zhuǎn)換為字符串類(lèi)型的值:
其實(shí)了解也很簡(jiǎn)單,畢竟是個(gè)規(guī)范,借用大佬一張圖:

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

Undefined,null,boolean
直接加上引號(hào),例如"null"

number 則有比較長(zhǎng)的規(guī)范,畢竟范圍比較大
常見(jiàn)的就是 "1" NaN則為"NaN" 基本等同于上面一條
對(duì)于負(fù)數(shù),則返回-+字符串 例如 "-2" 其他的先不考慮了。

對(duì)象則是先轉(zhuǎn)為原始值,再按照上面的步驟進(jìn)行處理。

valueOf

當(dāng)調(diào)用 valueOf 方法,采用如下步驟:

調(diào)用ToObject方法得到一個(gè)對(duì)象O

原始數(shù)據(jù)類(lèi)型轉(zhuǎn)換為對(duì)應(yīng)的內(nèi)置對(duì)象, 引用類(lèi)型則不變

調(diào)用該對(duì)象(O)內(nèi)置valueOf方法.

不同內(nèi)置對(duì)象的valueOf實(shí)現(xiàn):

String => 返回字符串值

Number => 返回?cái)?shù)字值

Date => 返回一個(gè)數(shù)字,即時(shí)間值,字符串中內(nèi)容是依賴(lài)于具體實(shí)現(xiàn)的

Boolean => 返回Boolean的this值

Object => 返回this

對(duì)照代碼更清晰一點(diǎn)

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
}})
//依賴(lài)于內(nèi)部實(shí)現(xiàn)
console.log(obj.valueOf())
運(yùn)算隱式轉(zhuǎn)換

前面提了那么多抽象概念,就是為了這里來(lái)理解具體轉(zhuǎn)換的。
對(duì)于+運(yùn)算來(lái)說(shuō),規(guī)則如下:

+號(hào)左右分別進(jìn)行取值,進(jìn)行ToPrimitive()操作

分別獲取左右轉(zhuǎn)換之后的值,如果存在String,則對(duì)其進(jìn)行ToString處理后進(jìn)行拼接操作。

其他的都進(jìn)行ToNumber處理

在轉(zhuǎn)換時(shí)ToPrimitive,除去Date為string外都按照ToPrimitive type為Number進(jìn)行處理

說(shuō)的自己都迷糊了快,一起結(jié)合代碼來(lái)看一下

1+"2"+false

左邊取原始值,依舊是Number

中間為String,則都進(jìn)行toString操作

左邊轉(zhuǎn)換按照toString的規(guī)則,返回"1"

得到結(jié)果temp值"12"

右邊布爾值和temp同樣進(jìn)行1步驟

temp為string,則布爾值也轉(zhuǎn)為string"false"

拼接兩者 得到最后結(jié)果 "12false"

我們看一個(gè)復(fù)雜的

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)

不管多復(fù)雜,按照上面的順序來(lái)吧。

1+obj1

左邊就不說(shuō)了,number

右邊obj轉(zhuǎn)為基礎(chǔ)類(lèi)型,按照type為number進(jìn)行

先調(diào)用valueOf() 得到結(jié)果為1

兩遍都是number,則進(jìn)行相加得到2

1+obj2

左邊為number

右邊同樣按照按照type為number進(jìn)行轉(zhuǎn)化

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

調(diào)用toString() return "a"

依據(jù)第二條規(guī)則,存在string,則都轉(zhuǎn)換為string進(jìn)行拼接

得到結(jié)果1a

obj1+obj2

兩邊都是引用,進(jìn)行轉(zhuǎn)換 ToPrimitive 默認(rèn)type為number

obj1.valueOf()為1 直接返回

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

調(diào)用toString() return "a"

依據(jù)第二條規(guī)則,存在string,則都轉(zhuǎn)換為string進(jìn)行拼接

得到結(jié)果1a

到這里相信大家對(duì)+這種運(yùn)算的類(lèi)型轉(zhuǎn)換了解的差不多了。下面就看一下另一種隱式類(lèi)型轉(zhuǎn)換

== 抽象相等比較

這種比較分為兩大類(lèi),

類(lèi)型相同

類(lèi)型不同

相同的就不說(shuō)了,隱式轉(zhuǎn)換發(fā)生在不同類(lèi)型之間。規(guī)律比較復(fù)雜,規(guī)范比較長(zhǎng),這里也不列舉了,大家可以查看抽象相等算法。簡(jiǎn)單總結(jié)一句,相等比較就不想+運(yùn)算那樣string優(yōu)先了,是以number優(yōu)先級(jí)為最高。概括而言就是,都盡量轉(zhuǎn)成number來(lái)進(jìn)行處理,這樣也可以理解,畢竟比較還是期望比較數(shù)值。那么規(guī)則大概如下:
對(duì)于x == y

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

 沒(méi)什么可解釋的了
 1 == 2 //false

如果存在對(duì)象,ToPrimitive() type為number進(jìn)行轉(zhuǎn)換,再進(jìn)行后面比較

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

存在boolean,按照ToNumber將boolean轉(zhuǎn)換為1或者0,再進(jìn)行后面比較

//boolean 先轉(zhuǎn)成number,按照上面的規(guī)則得到1  
//3 == 1 false
//0 == 0 true
3 == true // false
"0" == false //true 

如果x為string,y為number,x轉(zhuǎn)成number進(jìn)行比較

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

結(jié)束語(yǔ) 參考文章

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

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/95189.html

相關(guān)文章

  • 從 ++[[]][+[]]+[+[]]==10? 深入淺出弱類(lèi)型 JS隱式轉(zhuǎn)換

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

    miya 評(píng)論0 收藏0
  • 17道面試題徹底理解 JavaScript 中的類(lèi)型轉(zhuǎn)換

    摘要:隱式類(lèi)型轉(zhuǎn)換通常在邏輯判斷或者有邏輯運(yùn)算符時(shí)被觸發(fā)。一元加號(hào)執(zhí)行字符串的類(lèi)型轉(zhuǎn)換。邏輯運(yùn)算符和將值轉(zhuǎn)為型,但是會(huì)返回原始值不是。計(jì)算從表達(dá)式開(kāi)始,該表達(dá)式通過(guò)方法轉(zhuǎn)換為空字符串,然后轉(zhuǎn)換為??偨Y(jié)查看原文關(guān)注每日一道面試題詳解 類(lèi)型轉(zhuǎn)換是將值從一種類(lèi)型轉(zhuǎn)換為另一種類(lèi)型的過(guò)程(比如字符串轉(zhuǎn)數(shù)字,對(duì)象轉(zhuǎn)布爾值等)。任何類(lèi)型不論是原始類(lèi)型還是對(duì)象類(lèi)型都可以進(jìn)行類(lèi)型轉(zhuǎn)換,JavaScript 的...

    SKYZACK 評(píng)論0 收藏0
  • 深入理解JavaScript的類(lèi)型轉(zhuǎn)換

    摘要:等同于等同于其他類(lèi)型和布爾類(lèi)型之間的比較如果是布爾類(lèi)型,則返回的結(jié)果。 showImg(https://segmentfault.com/img/bVburFq?w=796&h=398); 前言 JavaScript作為一門(mén)弱類(lèi)型語(yǔ)言,我們?cè)诿刻斓木帉?xiě)代碼過(guò)程中,無(wú)時(shí)無(wú)刻不在應(yīng)用著值類(lèi)型轉(zhuǎn)換,但是很多時(shí)候我們只是在單純的寫(xiě),并不曾停下腳步去探尋過(guò)值類(lèi)型轉(zhuǎn)換的內(nèi)部轉(zhuǎn)換規(guī)則,最近通過(guò)閱讀你...

    W4n9Hu1 評(píng)論0 收藏0
  • 深入理解JavaScript的類(lèi)型轉(zhuǎn)換

    摘要:等同于等同于其他類(lèi)型和布爾類(lèi)型之間的比較如果是布爾類(lèi)型,則返回的結(jié)果。 showImg(https://segmentfault.com/img/bVburFq?w=796&h=398); 前言 JavaScript作為一門(mén)弱類(lèi)型語(yǔ)言,我們?cè)诿刻斓木帉?xiě)代碼過(guò)程中,無(wú)時(shí)無(wú)刻不在應(yīng)用著值類(lèi)型轉(zhuǎn)換,但是很多時(shí)候我們只是在單純的寫(xiě),并不曾停下腳步去探尋過(guò)值類(lèi)型轉(zhuǎn)換的內(nèi)部轉(zhuǎn)換規(guī)則,最近通過(guò)閱讀你...

    niuxiaowei111 評(píng)論0 收藏0
  • 深入理解JavaScript的類(lèi)型轉(zhuǎn)換

    摘要:等同于等同于其他類(lèi)型和布爾類(lèi)型之間的比較如果是布爾類(lèi)型,則返回的結(jié)果。 showImg(https://segmentfault.com/img/bVburFq?w=796&h=398); 前言 JavaScript作為一門(mén)弱類(lèi)型語(yǔ)言,我們?cè)诿刻斓木帉?xiě)代碼過(guò)程中,無(wú)時(shí)無(wú)刻不在應(yīng)用著值類(lèi)型轉(zhuǎn)換,但是很多時(shí)候我們只是在單純的寫(xiě),并不曾停下腳步去探尋過(guò)值類(lèi)型轉(zhuǎn)換的內(nèi)部轉(zhuǎn)換規(guī)則,最近通過(guò)閱讀你...

    shuibo 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<