中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

原來JS還可以這樣拆箱轉換詳解

發布時間:2020-09-16 00:35:55 來源:腳本之家 閱讀:147 作者:程序猿何大叔 欄目:web開發

前言

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

被我們忽略的表象

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

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 的執行順序并不固定,而是根據某個條件來決定的,那么是根據什么呢?那就是在拆箱轉換時,調用了對象的 ToPrimitive 內部函數時,其會根據執行上下文,自動傳入一個轉換類型參數,暫時給它命名為 hint。

ToPrimitive

在 JavaScript 標準中,規定了 ToPrimitive 函數,它是對象類型到基本類型轉換的實現者(即,拆箱轉換);但這是一個內部算法,是編程語言在內部執行時遵循的一套規則。

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

但是對于不同的操作,拆箱轉換的內部實現也有所區別,正如上面的例子所示。

「拆箱轉換」的調用規則及順序如下:

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

那么關于 hint 可取的三種值,都有什么含義?又什么情況對應什么值?

確定 hint 取值

string

當在希望是字符串操作,也即發生對象到字符串的轉換時,傳入內部函數 ToPrimitive 的參數值即為 string:

// output
alert(obj);

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

number

當在希望是數值操作,也即發生對象到數值的轉換時,傳入內部函數 ToPrimitive 的參數值即為 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

當在一些不確定需要將對象轉換成什么基礎類型的場景下,傳入內部函數 ToPrimitive 的參數值即為 default:

// binary plus
let total = car1 + car2;

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

結語

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

參考鏈接

  • 《重學前端》——極客時間APP
  • Object to primitive conversion
  • ToPrimitive

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

平度市| 望城县| 无锡市| 嫩江县| 常宁市| 井陉县| 甘德县| 建水县| 红河县| 盐山县| 枣强县| 武穴市| 龙门县| 界首市| 沽源县| 滁州市| 错那县| 水城县| 新邵县| 怀安县| 宣汉县| 福贡县| 靖西县| 民丰县| 措美县| 栾川县| 盐边县| 福州市| 柳林县| 郯城县| 封开县| 嫩江县| 沁水县| 股票| 临泽县| 富阳市| 涪陵区| 南雄市| 芜湖县| 台前县| 洞口县|