成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

【JS迷你書】類型轉(zhuǎn)換之拆箱操作

fuyi501 / 3180人閱讀

摘要:類型轉(zhuǎn)換之裝箱操作一文中說,因?yàn)槭侨躅愋驼Z言,我們可以像對(duì)待引用類型一樣對(duì)基本類型數(shù)據(jù)進(jìn)行引用類型才該有的屬性獲取操作。本文的主題關(guān)注相反的操作對(duì)引用類型進(jìn)行那些基本類型才該有的操作時(shí)會(huì)怎樣即,拆箱操作。

眾所周知,JS 中共有 7 種數(shù)據(jù)類型:Undefined、Null、Boolean、Number、String、Symbol 和 Object。前 6 者是基本類型,Object 是引用類型。

《類型轉(zhuǎn)換之裝箱操作》一文中說,因?yàn)?JS 是弱類型語言,我們可以像對(duì)待引用類型一樣對(duì)基本類型數(shù)據(jù)進(jìn)行引用類型“才該有的”屬性獲取操作。

比如,如下的代碼并不會(huì)報(bào)錯(cuò):

var?a?=?1;
a.x?=?2;

上述代碼運(yùn)行過程中,發(fā)生了“裝箱操作”,通過閱讀《ECMA-262》規(guī)范,我們知道瀏覽器內(nèi)部是調(diào)用 ToObject 操作來實(shí)現(xiàn)的,它把基本類型包裝成相應(yīng)的引用類型。例如把 1 包裝成了 new Number(1)。

本文的主題關(guān)注相反的操作:對(duì)引用類型進(jìn)行那些基本類型“才該有的”操作時(shí)會(huì)怎樣?即,“拆箱操作”。

比如,如下的代碼并不會(huì)報(bào)錯(cuò):

var?a??=?1;
var?b?=?{};
console.log(a?-?b);

對(duì)普通對(duì)象進(jìn)行減法操作時(shí),對(duì)象需要轉(zhuǎn)化為數(shù)字類型?!禘cma-262 Edition 5.1》第11.6.2節(jié)對(duì)減法操作符規(guī)范如下:

The production AdditiveExpression : AdditiveExpression - MultiplicativeExpression is evaluated as follows:

  1. Let lref be the result of evaluating AdditiveExpression.

  2. Let lval be GetValue(lref).

  3. Let rref be the result of evaluating MultiplicativeExpression.

  4. Let rval be GetValue(rref).

  5. Let lnum be ToNumber(lval).

  6. Let rnum be ToNumber(rval).

  7. Return the result of applying the subtraction operation to lnum and rnum. See the note below 11.6.3.

上述操作中第 5、6 步比較關(guān)鍵,調(diào)用了內(nèi)部操作 ToNumber:

Argument Type Result
Undefined NaN
Null +0
Boolean The result is 1 if the argument is true. The result is +0 if the argument is false.
Number The result equals the input argument (no conversion).
String See grammar and note below.
Object Apply the following steps:
1. Let primValue be ToPrimitive(input argument, hint Number).
2. Return ToNumber(primValue).

最后一行,處理Object時(shí),經(jīng)歷兩步:1. ToPrimitive。2. ToNumber。

ToPrimitive 操作正與 ToObject 相對(duì),表示轉(zhuǎn)化為基本類型:

Input Type Result
Undefined The result equals the input argument (no conversion).
Null The result equals the input argument (no conversion).
Boolean The result equals the input argument (no conversion).
Number The result equals the input argument (no conversion).
String The result equals the input argument (no conversion).
Object Return a default value for the Object. The default value of an object is retrieved by calling the [[DefaultValue]] internal method of the object, passing the optional hint PreferredType. The behaviour of the [[DefaultValue]] internal method is defined by this specification for all native ECMAScript objects in 8.12.8.

最后一行說,對(duì)象轉(zhuǎn)化為基本類型時(shí),是獲取的對(duì)象的默認(rèn)值。使用的是內(nèi)部[[DefaultValue]](hint),規(guī)范原文引用如下(補(bǔ)充:本文中的英文都可以不看的,我都會(huì)仔細(xì)說明的):

When the [[DefaultValue]] internal method of O is called with hint String, the following steps are taken:

  1. Let toString be the result of calling the [[Get]] internal method of object O with argument "toString".

  2. If IsCallable(toString) is true then,
    1. Let str be the result of calling the [[Call]] internal method of toString, with O as the this value and an empty argument list.

    2. If str is a primitive value, return str.

  3. Let valueOf be the result of calling the [[Get]] internal method of object O with argument "valueOf".

  4. If IsCallable(valueOf) is true then,
    1. Let val be the result of calling the [[Call]] internal method of valueOf, with O as the this value and an empty argument list.

    2. If val is a primitive value, return val.

  5. Throw a TypeError exception.

When the [[DefaultValue]] internal method of O is called with hint Number, the following steps are taken:

  1. Let valueOf be the result of calling the [[Get]] internal method of object O with argument "valueOf".

  2. If IsCallable(valueOf) is true then,
    1. Let val be the result of calling the [[Call]] internal method of valueOf, with O as the this value and an empty argument list.

    2. If val is a primitive value, return val.

  3. Let toString be the result of calling the [[Get]] internal method of object O with argument "toString".

  4. If IsCallable(toString) is true then,
    1. Let str be the result of calling the [[Call]] internal method of toString, with O as the this value and an empty argument list.

    2. If str is a primitive value, return str.
      Throw a TypeError exception.

  5. When the [[DefaultValue]] internal method of O is called with no hint, then it behaves as if the hint were Number, unless O is a Date object (see 15.9.6), in which case it behaves as if the hint were String.

When the [[DefaultValue]] internal method of O is called with no hint, then it behaves as if the hint were Number, unless O is a Date object (see 15.9.6), in which case it behaves as if the hint were String.

上述算法是說,根據(jù) hint 值采取不同的處理方式,比如 hint 是 String 時(shí),優(yōu)先調(diào)用對(duì)象的 toString 方法,如果返回值是基本類型值,返回該值,否則調(diào)用對(duì)象的 valueOf 方法,如果返回值是基本類型值,返回該值。否則報(bào)錯(cuò)。

hint 是 Number 時(shí),順序是反過來的,優(yōu)先調(diào)用 valueOf,如果其返回值不是基本類型,再調(diào)用 toString。另外,除了日期對(duì)象外,如果沒傳 hint 的話,其默認(rèn)值是 Number,因此 JS 中類型轉(zhuǎn)化時(shí),更偏愛 Number。

下面我們舉幾個(gè)例子看看:

var?a?=?{
??toString()?{
????return?3
??},
??valueOf()?{
????return?"30"
??}
};
console.log(a?-?5);?//?25

這里使用的是減法操作,此時(shí) hint 是 Number,因此先調(diào)用對(duì)象 a 的 valueOf 方法,其返回值 "30" 是字符串類型,是基本類型。因此 a - 5 變成了 "30" - 5。

再看:

var?a?=?{
??toString()?{
????return?{}
??},
??valueOf:?null
};
console.log(a?-?5);?//?Uncaught?TypeError:?Cannot?convert?object?to?primitive?value

對(duì)象 a,其方法 valueOf 不是函數(shù),因而看其 toString 方法,而該方法返回的是一個(gè)空對(duì)象,不是基本類型。因而報(bào)錯(cuò)。

再如:

var?o?=?{
??toString()?{
????return?"now?is:?"
??},
??valueOf:?function()?{
????return?"時(shí)間是:"
??}
};
var?d?=?new?Date();
console.log(o?+?d);?//?時(shí)間是:Mon?May?06?2019?13:56:39?GMT+0800?(中國標(biāo)準(zhǔn)時(shí)間)

這里使用了加法操作:

The production AdditiveExpression : AdditiveExpression + MultiplicativeExpression is evaluated as follows:

  1. Let lref be the result of evaluating AdditiveExpression.

  2. Let lval be GetValue(lref).

  3. Let rref be the result of evaluating MultiplicativeExpression.

  4. Let rval be GetValue(rref).

  5. Let lprim be ToPrimitive(lval).

  6. Let rprim be ToPrimitive(rval).

  7. If Type(lprim) is String or Type(rprim) is String, then
    Return the String that is the result of concatenating ToString(lprim) followed by ToString(rprim)

  8. Return the result of applying the addition operation to ToNumber(lprim) and ToNumber(rprim). See the Note below 11.6.3.

其中第 5、6 步直接獲取加號(hào)兩邊的基本類型。此時(shí)沒有都傳遞 hint,o 是普通對(duì)象,因此默認(rèn) hint 是 Number,使用的 valueOf 的返回值。而 d 是日期對(duì)象,默認(rèn) hint 是 String,優(yōu)先調(diào)用的是其 toString 方法。然后根據(jù)第 7 步,采用的是字符串拼接方法。

加法操作,這里再舉一例:

var?o?=?{
???toString:?function()?{
????return?2
??}
};
console.log(o?+?o);?//?4

這里不過多解釋了。

ToPrimitive 除了在四則運(yùn)算中大量用到外,關(guān)系運(yùn)算中也經(jīng)常使用。比如 == 操作。其他類型轉(zhuǎn)換等相關(guān)知識(shí)留給后續(xù)文章吧。

至此,“拆箱”已經(jīng)說完了。

本文完。

《JavaScript 迷你書》傳送門,全面夯實(shí)基礎(chǔ)

掘金收藏

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

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

相關(guān)文章

  • 關(guān)于Promise

    摘要:反之,操作失敗,對(duì)象由狀態(tài)轉(zhuǎn)換為狀態(tài),此時(shí)回調(diào)函數(shù)會(huì)執(zhí)行方法。這里需要注意的是,雖然在之后便執(zhí)行了方法,但是并不是意味著往后的對(duì)象不執(zhí)行了,其他的還是對(duì)象還是要執(zhí)行的,只是不會(huì)再調(diào)用函數(shù)。 在 掘金上看見一篇寫promise的文章,感覺作者寫的很棒,文章鏈接在這:八段代碼徹底掌握 Promise 。看完之后感覺學(xué)到了很多,所以又重新把JavaScript Promise迷你書(中文版)...

    546669204 評(píng)論0 收藏0
  • JavaScript隱式類型轉(zhuǎn)換

    摘要:所謂裝箱轉(zhuǎn)換,正是把基本類型轉(zhuǎn)換為對(duì)應(yīng)的對(duì)象,他是類型轉(zhuǎn)換中一種相當(dāng)重要的種類。拆箱轉(zhuǎn)換在標(biāo)準(zhǔn)中,規(guī)定了函數(shù),它是對(duì)象類型到基本類型的轉(zhuǎn)換即,拆箱轉(zhuǎn)換。拆箱轉(zhuǎn)換會(huì)嘗試調(diào)用和來獲得拆箱后的基本類型。 JavaScript隱式類型轉(zhuǎn)換 基本數(shù)據(jù)類型 ECMAScript 一共定義了七種 build-in types,其中六種為 Primitive Value,Null, Undefined...

    bingo 評(píng)論0 收藏0
  • Java編譯期優(yōu)化思維導(dǎo)圖

    摘要:本文參考自來自周志明深入理解虛擬機(jī)第版,拓展內(nèi)容建議讀者可以閱讀下這本書。和構(gòu)造方法一一對(duì)應(yīng),是同一概念在兩個(gè)級(jí)別的含義收斂的操作自動(dòng)保證執(zhí)行父類的執(zhí)行語句塊初始化類變量字符串加操作替換為或的操作 showImg(https://segmentfault.com/img/remote/1460000016240419?w=3876&h=3614); 本文參考自來自周志明《深入理解Jav...

    sorra 評(píng)論0 收藏0
  • JS進(jìn)階】你真的掌握變量和類型了嗎

    摘要:本文從底層原理到實(shí)際應(yīng)用詳細(xì)介紹了中的變量和類型相關(guān)知識(shí)。內(nèi)存空間又被分為兩種,棧內(nèi)存與堆內(nèi)存。一個(gè)值能作為對(duì)象屬性的標(biāo)識(shí)符這是該數(shù)據(jù)類型僅有的目的。 導(dǎo)讀 變量和類型是學(xué)習(xí)JavaScript最先接觸到的東西,但是往往看起來最簡(jiǎn)單的東西往往還隱藏著很多你不了解、或者容易犯錯(cuò)的知識(shí),比如下面幾個(gè)問題: JavaScript中的變量在內(nèi)存中的具體存儲(chǔ)形式是什么? 0.1+0.2為什...

    fuyi501 評(píng)論0 收藏0
  • 正則表達(dá)式迷你-筆記

    摘要:使用看完你就會(huì)正則表達(dá)式了四種操作驗(yàn)證切分提取替換第一章正則表達(dá)式字符匹配攻略正則表達(dá)式是匹配模式,要么匹配字符,要么匹配位置至少,至多匹配中的任一個(gè)字符范圍表示法如果要匹配則要么要么要么通配符,表示幾乎任意 API 使用 String#search String#split String#match String#replace RegExp#test Reg...

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

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

0條評(píng)論

閱讀需要支付1元查看
<