欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

原來JS還可以這樣拆箱轉(zhuǎn)換詳解

 更新時間:2019年02月01日 11:11:29   作者:程序猿何大叔  
這篇文章主要給大家介紹了關(guān)于JS拆箱轉(zhuǎn)換的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

在讀 Winter 大佬的《重學(xué)前端》欄目時,重溫了 JS 的「拆箱轉(zhuǎn)換」?!秆b箱轉(zhuǎn)換」與「拆箱轉(zhuǎn)換」以前都是了解的,今天來看,自己所謂的了解也真是一知半解。在閱讀 Winter 老師寫的內(nèi)容后,對「拆箱轉(zhuǎn)換」這個知識點還是不甚清楚,因此我再去深入地了解一番,參考資料詳見文末的「參考鏈接」。

被我們忽略的表象

首先,我們來看一下例子:

const a = {
 name: 'a',
 toString () {
  console.log(this);
  console.log('toString');
  return { name: 'toString' };
 },
 valueOf () {
  console.log(this);
  console.log('valueOf');
  return { name: 'valueOf' };
 }
};

a * 2;
// {name: "a", toString: ƒ, valueOf: ƒ}
// valueOf
// {name: "a", toString: ƒ, valueOf: ƒ}
// toString
// Uncaught TypeError: Cannot convert object to primitive value

a + "";
// {name: "a", toString: ƒ, valueOf: ƒ}
// valueOf
// {name: "a", toString: ƒ, valueOf: ƒ}
// toString
// Uncaught TypeError: Cannot convert object to primitive 

alert(a);
// {name: "a", toString: ƒ, valueOf: ƒ}
// toString
// {name: "a", toString: ƒ, valueOf: ƒ}
// valueOf
// Uncaught TypeError: Cannot convert object to primitive value

可以看到,toString 和 valueOf 的執(zhí)行順序并不固定,而是根據(jù)某個條件來決定的,那么是根據(jù)什么呢?那就是在拆箱轉(zhuǎn)換時,調(diào)用了對象的 ToPrimitive 內(nèi)部函數(shù)時,其會根據(jù)執(zhí)行上下文,自動傳入一個轉(zhuǎn)換類型參數(shù),暫時給它命名為 hint。

ToPrimitive

在 JavaScript 標(biāo)準(zhǔn)中,規(guī)定了 ToPrimitive 函數(shù),它是對象類型到基本類型轉(zhuǎn)換的實現(xiàn)者(即,拆箱轉(zhuǎn)換);但這是一個內(nèi)部算法,是編程語言在內(nèi)部執(zhí)行時遵循的一套規(guī)則。

對象到 String 和 Number 的轉(zhuǎn)換都遵循“先拆箱再轉(zhuǎn)換”的規(guī)則。通過拆箱轉(zhuǎn)換,把對象變成基本類型,再從基本類型轉(zhuǎn)換為對應(yīng)的 String 或者 Number。

但是對于不同的操作,拆箱轉(zhuǎn)換的內(nèi)部實現(xiàn)也有所區(qū)別,正如上面的例子所示。

「拆箱轉(zhuǎn)換」的調(diào)用規(guī)則及順序如下:

  • 檢查對象中是否有用戶顯式定義的 [Symbol.toPrimitive] 方法,如果有,直接調(diào)用;
  • 如果沒有,則執(zhí)行原內(nèi)部函數(shù) ToPrimitive,然后判斷傳入的 hint 值,如果其值為 string,順序調(diào)用對象的 toString 和 valueOf 方法(其中 toString 方法一定會執(zhí)行,如果其返回一個基本類型值,則返回、終止運算,否則繼續(xù)調(diào)用 valueOf 方法);
  • 如果判斷傳入的 hint 值不為 string,則就可能為 number 或者 default 了,均會順序調(diào)用對象的 valueOf 和 toString 方法(其中 valueOf 方法一定會執(zhí)行,如果其返回一個基本類型值,則返回、終止運算,否則繼續(xù)調(diào)用 toString 方法);

來看一下第一種情況:

const b = {
 [Symbol.toPrimitive] (hint) {
  console.log(`hint: ${hint}`);
  return {};
 },
 toString () {
  console.log('toString');
  return 1;
 },
 valueOf () {
  console.log('valueOf');
  return 2;
 }
};

alert(b); // hint: string 
b + ''; // hint: default
b + 500; // hint: default
+b; // hint: number
b * 1; // hint: number

第二、三種情況:

const c = {
 toString () {
  console.log('toString');
  return 1;
 },
 valueOf () {
  console.log('valueOf');
  return 2;
 }
};

alert(c); // 打印出 toString 并 alert 出 1
c + ''; // 先后打印出 valueOf,"2"
c + 500; // 先后打印出 valueOf,502
+c; // 先后打印出 valueOf,2
c * 1; // 先后打印出 valueOf,2

那么關(guān)于 hint 可取的三種值,都有什么含義?又什么情況對應(yīng)什么值?

確定 hint 取值

string

當(dāng)在希望是字符串操作,也即發(fā)生對象到字符串的轉(zhuǎn)換時,傳入內(nèi)部函數(shù) ToPrimitive 的參數(shù)值即為 string:

// output
alert(obj);

// using object as a property key
anotherObj[obj] = 123;

number

當(dāng)在希望是數(shù)值操作,也即發(fā)生對象到數(shù)值的轉(zhuǎn)換時,傳入內(nèi)部函數(shù) ToPrimitive 的參數(shù)值即為 number:

// explicit conversion
let num = Number(obj);

// maths (except binary plus)
let n = +obj; // unary plus
let delta = date1 - date2;

// less/greater comparison
let greater = user1 > user2;

default

當(dāng)在一些不確定需要將對象轉(zhuǎn)換成什么基礎(chǔ)類型的場景下,傳入內(nèi)部函數(shù) ToPrimitive 的參數(shù)值即為 default:

// binary plus
let total = car1 + car2;

// obj == string/number/symbol
if (user == 1) { ... };

結(jié)語

如果親愛的讀者們在本文中發(fā)現(xiàn)了什么錯誤,或者有什么不同的意見,還請留言,一起討論,一起將隱藏的、晦澀的點提出來,然后解決掉。

參考鏈接

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關(guān)文章

  • JavaScript 不只是腳本

    JavaScript 不只是腳本

    JavaScript 不只是腳本...
    2007-05-05
  • uni-app如何頁面?zhèn)鲄?shù)的幾種方法總結(jié)

    uni-app如何頁面?zhèn)鲄?shù)的幾種方法總結(jié)

    這篇文章主要介紹了uni-app如何頁面?zhèn)鲄?shù)的幾種方法總結(jié),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • 為什么說JavaScript預(yù)解釋是一種毫無節(jié)操的機制詳析

    為什么說JavaScript預(yù)解釋是一種毫無節(jié)操的機制詳析

    這篇文章主要給大家介紹了關(guān)于為什么說JavaScript預(yù)解釋是一種毫無節(jié)操的機制的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧
    2018-11-11
  • 基于mouseout和mouseover等類似事件的冒泡問題解決方法

    基于mouseout和mouseover等類似事件的冒泡問題解決方法

    這篇文章主要介紹了關(guān)于mouseout和mouseover等類似事件的冒泡問題解決方法。需要的朋友可以過來參考下,希望對大家有所幫助
    2013-11-11
  • 微信小程序?qū)崿F(xiàn)表單驗證

    微信小程序?qū)崿F(xiàn)表單驗證

    這篇文章主要為大家詳細介紹了微信小程序?qū)崿F(xiàn)表單驗證,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • typeScript?核心基礎(chǔ)之接口interface

    typeScript?核心基礎(chǔ)之接口interface

    本篇文章主要介紹?typeScript?中接口是啥?如何定義的?接口是如何進行擴展的以及類如何實現(xiàn)接口,接下來和小編一起進入下面文章一起學(xué)習(xí)?typeScript?接口
    2022-02-02
  • JavaScript代碼復(fù)用模式實例分析

    JavaScript代碼復(fù)用模式實例分析

    任何編程都提出代碼復(fù)用,否則話每次開發(fā)一個新程序或者寫一個新功能都要全新編寫的話,效率太差了,接下來我們將針對代碼復(fù)用來進行討論,需要的朋友可以參考下
    2012-12-12
  • D3.js實現(xiàn)散點圖和氣泡圖的方法詳解

    D3.js實現(xiàn)散點圖和氣泡圖的方法詳解

    這篇文章將會給大家介紹了另外兩種可視化圖表,利用D3.js實現(xiàn)散點圖和氣泡圖,文章通過多個方面介紹的非常詳細,下面來一起看看吧。
    2016-09-09
  • 帶有定位當(dāng)前位置的百度地圖前端web api實例代碼

    帶有定位當(dāng)前位置的百度地圖前端web api實例代碼

    這篇文章主要介紹了帶有定位當(dāng)前位置的百度地圖前端web api實例代碼 的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-06-06
  • 面試官常問之說說js中var、let、const的區(qū)別

    面試官常問之說說js中var、let、const的區(qū)別

    var、let和const都是JavaScript中用來聲明變量的關(guān)鍵字,并且let和 const關(guān)鍵字是在 ES6 中才新增的,下面這篇文章主要給大家介紹了關(guān)于var、let、const區(qū)別的相關(guān)資料,需要的朋友可以參考下
    2022-03-03

最新評論