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

資訊專欄INFORMATION COLUMN

33 個(gè) js 核心概念(四):顯式 (名義) 與 隱式 (鴨子)類型轉(zhuǎn)換

hoohack / 2800人閱讀

摘要:相對(duì)于顯式使用,隱式轉(zhuǎn)換則更加簡(jiǎn)潔。隱式轉(zhuǎn)換為布爾值將其他類型值隱式轉(zhuǎn)換為布爾值是我們最常用的一種轉(zhuǎn)換。在以下場(chǎng)景中,都是進(jìn)行判斷,而只要傳入的值不是布爾值,都會(huì)通過(guò)隱式類型轉(zhuǎn)換轉(zhuǎn)為布爾值。原文地址阿木木的博客與隱式鴨子類型轉(zhuǎn)換

前言

說(shuō)實(shí)話,JavaScript 的類型轉(zhuǎn)換是個(gè)相當(dāng)頭疼的問(wèn)題,無(wú)論是對(duì)于初學(xué)者還是有經(jīng)驗(yàn)的老司機(jī)。它的難處并不在于概念多難理解,而是情況多且雜,看似相同的情況結(jié)果卻又出人意料,很少有人能保證時(shí)刻都能做出正確的判斷。

因此,這篇文章希望能講的足夠細(xì)致和明確,讓大家能夠在日常使用中,能夠盡快的搞清楚類型轉(zhuǎn)換的順序和結(jié)果。

長(zhǎng)文預(yù)警,建議先 mark, 分多次查看。

一、類型轉(zhuǎn)換 1. 什么叫類型轉(zhuǎn)換?

我們知道,JavaScript 中存在七種數(shù)據(jù)類型,在必要的時(shí)候,我們會(huì)對(duì)不同類型的值進(jìn)行相互間的轉(zhuǎn)換。比如說(shuō),在進(jìn)行條件判斷時(shí),我們需要將其他類型的值轉(zhuǎn)為布爾類型值,在使用 console.log() 打印內(nèi)容時(shí),需要將其轉(zhuǎn)為字符串輸出。

2. JavaScript 中的類型轉(zhuǎn)換方式有哪些?

在 JavaScript 中,分為顯式類型轉(zhuǎn)換和隱式類型轉(zhuǎn)換。

其中,顯式類型轉(zhuǎn)換是我們?yōu)榱斯δ苄枰藶榈膶⒁环N類型的值轉(zhuǎn)換為另一中類型,轉(zhuǎn)換的時(shí)機(jī)和結(jié)果都是我們預(yù)期的;而隱式類型轉(zhuǎn)換則是 JavaScript 在代碼運(yùn)行時(shí),未經(jīng)我們?cè)试S而進(jìn)行的強(qiáng)制類型轉(zhuǎn)換。

二、顯式類型轉(zhuǎn)換 1. 其他類型轉(zhuǎn)換為字符串( ToString )
值類型 例子 轉(zhuǎn)換后 調(diào)用法則
number 34 "34" String(34)
boolean true "true" String(true)
boolean false "false" String(false)
undefiend undefined "undefined" String(undefined)
null null "null" String(null)
object { a: "fa" } "[object Object]" String({a: "fa"})
object new String(45) "45" String(new String(45))
object [1, 2] "1,2" String([1,2])
object function() {var d;} "function() { var d; }" String(function() {var d;})

其他類型的值轉(zhuǎn)換為字符串,是通過(guò)調(diào)用原生函數(shù)String()實(shí)現(xiàn),但不同類型值的實(shí)現(xiàn)卻有明顯的差異。

對(duì)于基本類型的值,直接將其轉(zhuǎn)化為值的字符串形式。而對(duì)于對(duì)象類型來(lái)說(shuō),便有些復(fù)雜了。

首先,每個(gè)對(duì)象內(nèi)部都有一個(gè) [[Class]] 屬性,我們通過(guò)Object.prototype.toString() 方法可以得到這個(gè)屬性的字符串值。

對(duì)于對(duì)象(如{ a: "ff"; })而言,除非自己定義 toString() 方法,否則,調(diào)用 String() 方法將返回和調(diào)用 Object.prototype.toString() 相同的值。(如 : "[object Object]")。

const obj_1 = {
  b: "lalala"
};
const obj_2 = {
  toString() {
    return "fasfa";
  }
};
String(obj_1); // "[object Object]"
String(obj_2); // "fasfa"

其次, JavaScript 中,除了普通對(duì)象,還有以下幾種:

封裝對(duì)象

對(duì)于基本類型值 stringnumberboolean 是沒(méi)有 .lengthtoString() 方法的,因此,JavaScript 提供了內(nèi)建函數(shù) String()Number()Boolean() ,通過(guò) new 調(diào)用后會(huì)將基本類型值封裝為一個(gè)對(duì)象。

如果想要取到封裝對(duì)象中的基本類型值,可以使用 valueOf() 方法。

// string 類型
const a = "i am string";
typeof a; //  "string"
// string 封裝對(duì)象
const b = new String("i am sringObject");
typeof b; // "object"
// 拆封
b.valueOf(); // i am sringObject

那對(duì)于封裝對(duì)象,String() 會(huì)返回什么值呢?

事實(shí)上,封裝對(duì)象對(duì)于 toString() 方法進(jìn)行了封裝,因此,對(duì)封裝對(duì)象調(diào)用 String() 方法,將會(huì)返回封裝對(duì)象調(diào)用toString() 方法返回的值。

const numObj = new Number(false); // Number {0}
numObj.toString(); // "0"
String(numObj); // "0"

函數(shù)

對(duì)于函數(shù)來(lái)說(shuō),它也包裝了自己的 toString()方法,因此,調(diào)用 String() 方法時(shí)將返回函數(shù)字符串化后的值。

function bar() {
  console.log("bar");
}
String(bar); // "function bar() {?  console.log("bar");?}"
bar.toString(); // "function bar() {?  console.log("bar");?}"
Object.prototype.toString.call(bar); // "[object Function]"

從上例可以看到,String()toString() 方法調(diào)用的是函數(shù)自己封裝的toSring(),如果調(diào)用對(duì)象的 toString() 方法,則函數(shù)與普通對(duì)象一樣,返回的是函數(shù)對(duì)象內(nèi)部的 [[Class]] 屬性。

數(shù)組

數(shù)組同函數(shù)一樣,同樣包裝了自己的 toString() 方法。此方法會(huì)將數(shù)組中的每一項(xiàng)用逗號(hào)連接成一個(gè)字符串。

const arr = [1,4,6];
String(arr); // "1,4,6"
arr.toString(); // "1,4,6"
Object.prototype.toString.call(arr); // "[object Array]"

2. 其他類型值轉(zhuǎn)為數(shù)字( ToNumber )

同樣,先感受一下什么叫絕望?~~

值類型 例子 轉(zhuǎn)換后 調(diào)用法則
string "34" 34 Number("34")
string "" 0 Number("")
string "34fad" NaN Number("34fad")
string "34fad"、"34.24"、"34" 34 parseInt("34fad")
string "34fad"、"34" 34 parseFloat(值)
string "34.34" 34.34 parseFloat(值)
boolean true 1 Number(true)
boolean false 0 Number(false)
undefiend undefined NaN Number(undefined)
null null 0 Number(null)
object { a: "fa" } NaN Number({a: "fa"})
object new String("fff") NaN Number(new String("fff"))
object [] 0 Number([])
object [1, 2] NaN Number([1,2])
object function() {var d;} NaN Number(function() {var d;})

看完一臉懵逼有沒(méi)有?!哈哈,不用害怕,乍看上去,大概會(huì)覺(jué)得異常混亂,其實(shí)稍加整理,不外乎以下幾種情況:

轉(zhuǎn)換后值為 NaN

數(shù)字與字符串不同,并不是任何類型值都能轉(zhuǎn)為數(shù)字,因此,就會(huì)有 NaN,意思就是 not a number

諸如包含非數(shù)字的字符串、undefined、非空數(shù)組,部分對(duì)象,都是我們知道無(wú)法轉(zhuǎn)化為一個(gè)數(shù)字的。

boolean 類型值

對(duì)于 truefalsetrue 轉(zhuǎn)換為 1,false 轉(zhuǎn)為 0。

帶有數(shù)字的字符串

從上面我們可以看到,對(duì)于帶有數(shù)字的字符串,有三種方法進(jìn)行轉(zhuǎn)換,但規(guī)則不同。

Number() 方法會(huì)對(duì)字符串整體進(jìn)行轉(zhuǎn)換, 它會(huì)先判斷這個(gè)字符串是否是個(gè)正確的數(shù)字字符串,如果不是,則會(huì)返回 NaN

parseInt() 方法則會(huì)對(duì)字符串從左往右依次解析,直到遇到第一個(gè)非數(shù)字字符(包括小數(shù)點(diǎn)),如果最左邊的字符是非數(shù)字字符,則返回 NaN

parseFloat() 方法解析順序同 parseInt() 相同,不同的是它遇到第一個(gè)小數(shù)點(diǎn)時(shí)會(huì)正常往右繼續(xù)解析,直至遇到非數(shù)字字符停止。

其實(shí)嚴(yán)格來(lái)講,只有 `Number()` 方法是進(jìn)行轉(zhuǎn)換操作,而后兩者屬于將字符串**解析** 為數(shù)字,但為了講解方便,我將它們放在一起講述。

對(duì)象

對(duì)于對(duì)象而言,會(huì)先將對(duì)象轉(zhuǎn)為基本類型值( ToPrimitive ),再對(duì)基本類型值調(diào)用 Number() 方法。

那如何將對(duì)象轉(zhuǎn)為基本類型值?首先會(huì)調(diào)用對(duì)象的 valueOf() 方法,如果沒(méi)有此方法或者此方法返回值不是基本類型值,則會(huì)調(diào)用toString() 方法,如果 toString() 方法不存在或者返回值也不是基本類型值,會(huì)產(chǎn)生 TypeError 錯(cuò)誤。

// 普通對(duì)象
const nomalObj = {
  a: "56"
};
nomalObj .valueOf(); // { a: "56"}
nomalObj.toString(); // "[object Object]"
// Number(nomalObj) 相當(dāng)于Number("[object Object]") 
Number("[object Object]"); // NaN
Number(nomalObj); // NaN

// valueOf() 返回基本類型值的對(duì)象
const obj_1 = {
  a: "56",
  valueOf: function() {
    return "23";
  }  
};
obj_1.valueOf(); // "23"
// Number(obj_1) 相當(dāng)于 Number("23");
Number("23"); // 23
Number(obj_1); // 23

// valueOf() 返回非基本類型值,toString() 返回基本類型值的對(duì)象
const obj_2 = {
  a: "56",
  valueOf: function() {
    return {b: 34}
  },
  toString: function() {
    return false;
  }
};
obj_2.valueOf(); // {b: 34}
obj_2.toString(); // false
// Number(obj_2) 相當(dāng)于 Number(false)
Number(obj_2); // 0
Number(false); // 0

上面的規(guī)則,適用于我們所說(shuō)的所有對(duì)象,比如數(shù)組,封裝對(duì)象和函數(shù)。

3. 其他類型轉(zhuǎn)換為 boolean 值( ToBoolean )

我們可以通過(guò) Boolean()方法 或!!運(yùn)算符來(lái)顯式的將一個(gè)值轉(zhuǎn)換為布爾值。

相對(duì)來(lái)說(shuō),判斷一個(gè)值是 true 還是 false 則比較容易,我們只需要記住以下幾種值會(huì)轉(zhuǎn)換為 false,而其他值,均為 true

undefined

null

false

+0、-0 和 NaN

""

當(dāng)我們看到 []、{} 甚至是 """" 時(shí),也一定要記住,它們是真值。

Boolean(false); // fasle
Boolean([]); //true
Boolean({}); //true
Boolean(""); // false
Boolean(""""); // true
Boolean("false"); // true
三、隱式強(qiáng)制類型轉(zhuǎn)換

除了進(jìn)行強(qiáng)制類型轉(zhuǎn)換,JavaScript 會(huì)在運(yùn)行時(shí)根據(jù)需要,自動(dòng)進(jìn)行類型的轉(zhuǎn)換,盡管這個(gè)特點(diǎn)飽受爭(zhēng)議,但不得不承認(rèn),某些情況下我們?nèi)耘f更喜歡使用某些隱式轉(zhuǎn)換規(guī)則。

一旦某些隱式的規(guī)則被接受并廣泛使用,從某種意義上來(lái)講,這些規(guī)則便同顯式轉(zhuǎn)換一樣。

1. 奇怪的 + 號(hào)

先看一一個(gè)最常見(jiàn)的例子:

const a = 5;
const b = "6";
console.log(a+a); // 10
console.log(a+b); // "56"
console.log(b+b); // "66"

之所以會(huì)產(chǎn)生上例中的狀況,原因就在于在JavaScript 中,+ 運(yùn)算符既可以作用于number 類型值,也可以作用于 string 類型值。前者進(jìn)行數(shù)字相加,后者則進(jìn)行字符串的拼接。

這就是為什么5 + 5 = 10"6" + "6" = "66"。而當(dāng) + 號(hào)兩邊既有數(shù)字也有字符串時(shí),則會(huì)隱式的將數(shù)字轉(zhuǎn)換為字符串,然后進(jìn)行字符串的拼接。

那兩邊沒(méi)有字符串的情況呢?比如:

const a = [1,4];
const b = [2,3];
const c = 4;
console.log(a+c); // "1,44"
console.log(a+b); // "1,42,3"

為什么會(huì)這樣?原來(lái)只要 + 的其中一個(gè)操作數(shù)可以通過(guò)某種方式(toPrimitive)轉(zhuǎn)換為字符串,就會(huì)進(jìn)行字符串的拼接。

我們知道,數(shù)組[1,4] 可以通過(guò) toString() 方法返回字符串 "1,4",因此,[1,4] + 4 就相當(dāng)于 "1,4" + 4

因?yàn)檫@個(gè)特性,我們?cè)谙雽⒁粋€(gè)數(shù)字 a 轉(zhuǎn)換為字符串時(shí),便可以直接使用 a + "" 的形式即可。相對(duì)于顯式使用String(a),隱式轉(zhuǎn)換則更加簡(jiǎn)潔。

從數(shù)組的例子我們可以看到,除了數(shù)字,其他類型的值也可以通過(guò) + " " 的形式轉(zhuǎn)化為字符串。

const a = {b: "2"}
console.log( a+ ""); // "[object Object]"

但有一點(diǎn)需要注意,對(duì)于對(duì)象而言,使用 String() 方法是直接取這個(gè)對(duì)象 toString() 方法的返回值,而 + " " ,則會(huì)對(duì)這個(gè)對(duì)象調(diào)用 valueOf 反法,然后對(duì) valueOf 的返回值調(diào)用 toString(),將其轉(zhuǎn)換為字符串。

const a = {
  toString: function() { return 45 },
  valueOf: function() { return 4}
 };
String(a); // "45"
a + " "; //  // "4"

好在除非我們特意去改變一個(gè)對(duì)象的 valueOf 及 "toString()" 方法,通過(guò)上述兩個(gè)方式的轉(zhuǎn)換后的結(jié)果都是一致的。

2. 有用的 - 號(hào)

+ 號(hào)不同的是,- 號(hào)只能用于數(shù)字的相減,對(duì)于它兩邊的操作數(shù),都會(huì)經(jīng)過(guò)隱式類型轉(zhuǎn)換轉(zhuǎn)為數(shù)字。

const a = "34";
const b = "4";
console.log(a - b); // 30
const c = "dd";
console.log(a - c); // NaN
const d = [4];
console.log(a - d); // 30

根據(jù)上例,我們可看到,如果 - 號(hào)兩邊是字符串,則會(huì)將他們強(qiáng)制轉(zhuǎn)換為數(shù)字,如果 - 兩邊不是字符串,則會(huì)先將其轉(zhuǎn)為字符串,再將這個(gè)字符串轉(zhuǎn)為數(shù)字。

3. 隱式轉(zhuǎn)換為布爾值

將其他類型值隱式轉(zhuǎn)換為布爾值是我們最常用的一種轉(zhuǎn)換。因?yàn)槌绦虻木帉?xiě)實(shí)質(zhì)上就是不停的進(jìn)行判斷。

在以下場(chǎng)景中,都是進(jìn)行判斷,而只要傳入的值不是布爾值,都會(huì)通過(guò)隱式類型轉(zhuǎn)換轉(zhuǎn)為布爾值。

if (..) {} 語(yǔ)句中的條件判斷表達(dá)式。

for ( .. ; .. ; ..) 語(yǔ)句中的條件判斷表達(dá)式。

while (..) do ... while ( ..) 中的條件判斷表達(dá)式。

? : 中的條件判斷表達(dá)式。

邏輯或 || 或邏輯與 && 左邊的操作數(shù)。

在這些情況下,都將會(huì)進(jìn)行其他類型值到布爾類型值的隱式轉(zhuǎn)換,規(guī)則同顯式調(diào)用 Boolean()

上面就是不同數(shù)據(jù)類型直接顯式或隱式的轉(zhuǎn)換規(guī)則,我們不需要將每一種情況都牢記在心,但有必要對(duì)他們進(jìn)行充分的了解,這可以保證我們?cè)趯?shí)際寫(xiě)代碼時(shí)避免不少奇怪又難以排查的 bug 。

原文地址:阿木木的博客 與 隱式 (鴨子)類型轉(zhuǎn)換)

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

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

相關(guān)文章

  • 《Kotlin 極簡(jiǎn)教程 》第4章 基本數(shù)據(jù)類型類型系統(tǒng)

    摘要:本章我們來(lái)學(xué)習(xí)一下的基本數(shù)據(jù)類型與類型系統(tǒng)。字符串就是一個(gè)抽象數(shù)據(jù)類型。如果程序語(yǔ)言的語(yǔ)法中含有類型標(biāo)記,就稱該語(yǔ)言是顯式類型化的,否則就稱為隱式類型化的。但是,可以把中對(duì)應(yīng)的這幾種基本數(shù)據(jù)類型,理解為的基本類型的裝箱類。 第4章 基本數(shù)據(jù)類型與類型系統(tǒng) 《Kotlin極簡(jiǎn)教程》正式上架: 點(diǎn)擊這里 > 去京東商城購(gòu)買(mǎi)閱讀 點(diǎn)擊這里 > 去天貓商城購(gòu)買(mǎi)閱讀 非常感謝您親愛(ài)的讀...

    MoAir 評(píng)論0 收藏0
  • [譯] Python 學(xué)習(xí) —— __init__() 方法 4

    摘要:同時(shí),有多個(gè)類級(jí)別的靜態(tài)構(gòu)造函數(shù)的方法。這個(gè)累贅,無(wú)論如何,是被傳遞到每個(gè)單獨(dú)的對(duì)象構(gòu)造函數(shù)表達(dá)式中。我們可能只有幾個(gè)特定的擔(dān)憂,提供額外關(guān)鍵字參數(shù)給構(gòu)造函數(shù)。 注:原書(shū)作者 Steven F. Lott,原書(shū)名為 Mastering Object-oriented Python 沒(méi)有__init__()的無(wú)狀態(tài)對(duì)象 下面這個(gè)示例,是一個(gè)簡(jiǎn)化去掉了__init__()的類。這是一個(gè)常見(jiàn)...

    yvonne 評(píng)論0 收藏0
  • 該死的IEEE-754浮點(diǎn)數(shù),說(shuō)「約」就「約」,你的底線呢?以JS名義來(lái)好好查查你

    摘要:而的浮點(diǎn)數(shù)設(shè)置的偏移值是,因?yàn)橹笖?shù)域表現(xiàn)為一個(gè)非負(fù)數(shù),位,所以,實(shí)際的,所以。這是因?yàn)樗鼈冊(cè)谵D(zhuǎn)為二進(jìn)制時(shí)要舍入部分的不同可能造成的不同舍 IEEE 754 表示:你盡管抓狂、罵娘,但你能完全避開(kāi)我,算我輸。 一、IEEE-754浮點(diǎn)數(shù)捅出的那些婁子 首先我們還是來(lái)看幾個(gè)簡(jiǎn)單的問(wèn)題,能說(shuō)出每一個(gè)問(wèn)題的細(xì)節(jié)的話就可以跳過(guò)了,而如果只能泛泛說(shuō)一句因?yàn)镮EEE754浮點(diǎn)數(shù)精度問(wèn)題,那么下文還是...

    gaosboy 評(píng)論0 收藏0
  • 復(fù)習(xí)Javascript專題(一):基本概念部分

    摘要:一數(shù)據(jù)類型基本類型引用類型類型判斷返回結(jié)果未定義布爾值字符串?dāng)?shù)值對(duì)象或者函數(shù)拓展堆棧兩種數(shù)據(jù)結(jié)構(gòu)堆隊(duì)列優(yōu)先,先進(jìn)先出由操作系統(tǒng)自動(dòng)分配釋放,存放函數(shù)的參數(shù)值,局部變量的值等。 一、數(shù)據(jù)類型 基本類型:`Null Boolean String Undefined Number(NB SUN)` 引用類型:`Array Function Object` 類型判斷:typeof 返回結(jié)果...

    LiangJ 評(píng)論0 收藏0
  • JS 作用域 閉包 this 原型 知識(shí)點(diǎn)總結(jié)

    摘要:如果你能看懂以下兩張圖那就可以跳過(guò)本總結(jié)了當(dāng)然點(diǎn)個(gè)贊再走啊喂啊喂分割線你不知道的上冊(cè)作用域和閉包和查詢可以理解為查找變量賦值的目標(biāo)和源頭當(dāng)然賦值可以是隱晦的查詢失敗將在嚴(yán)格模式下導(dǎo)致拋出非嚴(yán)格模式下則會(huì)自動(dòng)創(chuàng)建新變量額分別是修改原有作用域和 如果你能看懂以下兩張圖, 那就可以跳過(guò)本總結(jié)了, 當(dāng)然, 點(diǎn)個(gè)贊再走啊喂! (#`O′)! showImg(https://segmentfau...

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

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

0條評(píng)論

閱讀需要支付1元查看
<