iT邦幫忙

2023 iThome 鐵人賽

DAY 17
0
自我挑戰組

我的日常學習雜記與筆記整理系列 第 30

Day - 30 引數型別(二) 與 型別轉換 筆記

  • 分享至 

  • xImage
  •  

當使用某種類型的值調用一個函式,而此函式實際上需要另一種類型的值時,JavaScript會嘗試自動將其轉換為需要的類型。

比如,若寫一個函式需要一個字串引數,但調用它時卻傳遞了一個不同類型的值,那麼 JavaScript 會嘗試將這個值轉換為字串使函式能夠正確運作。

這對於原始資料型別 (primitive data type,如 numberbooleannullundefined 等) 是有效的,而所有物件也都擁有 toString() 方法(但實際行為不一定總是返回有用的結果), 因此在這些情況下,不太可能發生錯誤:

// 整數相加
var num1 = 5;
var num2 = 10;
var result = num1 + num2; 
console.log(result); //  15

// 整數和字串相加
var num = 5;
var str = "10";
var result = num + str; 
console.log(result); // "510"

// 布林值與數字相加
var bool = true;
var num = 7;
var result = bool + num; 
console.log(result); //  結果是數字8(true轉換為1)

// null和undefined的轉換
var value1 = null;
var value2 = undefined;
var result1 = value1 + 10; 
var result2 = value2 + "hello"; 
console.log(result1); // 結果是數字 10(null轉換為0)
console.log(result2); // 結果是字串 "undefinedhello"

// 物件的toString()方法
var obj = { name: "John" };
var str = obj.toString();
console.log(str);  // str現在包含字串 "[object Object]"

// 物件的隱式轉換
var num = 42;
var obj = { value: 10 };
var result = num + obj; // 結果是字串 "42",因為num被轉換為字串,然後與obj的字串結合
console.log(result); // "42[object Object]"

JavaScript會根據需要自動執行類型轉換,所以通常不會導致錯誤,但這種情況並非永遠成立,有時可能導致意外的結果,因此在撰寫程式碼時需要謹慎處理類型轉換

書中提到的 arraycopy()範例 ,它要求其第一個引數必須是一個陣列。若傳給 arraycopy() 函式的第一個引數不是陣列或類似陣列的物件,那麼任何合理的、正確實現 arraycopy() 函式的程式碼都不會運作正確,從而導致錯誤。 這是因為 arraycopy() 函式的設計和預期是要處理陣列,而不是其他類型的物件:

// 書中範例
/*
 型別 array : from, 
 型別 index : from_start, 
 型別 array : to, 
 型別 index : to_start, 
 型別 integer : length
*/
function arraycopy(from, from_start, to, to_start, length){
  //程式碼
}

因此,除非寫的是一個只會被調用一兩次的一次性函式,否則最好增加檢查函式引數類型的程式碼。好處是,若傳遞了不正確的引數,函式會立即拋出錯誤,避免不正確的引數導致後續執行中的錯誤。

一次性函式: 很少次被呼叫的函式,而不是常見的或被多次使用的函式。

使用isArrayLike()的函式來確保引數類似陣列

若引數是類似陣列的,則函式會計算這些元素的總和,並忽略 nullundefined 值。

// 書中範例

// 返回陣列(或類似陣列物件)a的元素之和。
// a的元素必須都是數字,而 null 和 undefined 會被忽略。
function sum(a) {
  if (isArrayLike(a)) {
    var total = 0;
    for (var i = 0; i < a.length; i++) {
      // 遍歷所有元素
      var element = a[i];
      if (element == null) {
        continue; // 跳過null和undefined
      }
      if (isFinite(element)) {
        total += element;
      } else throw new Error("sum(): elements must be finite numbers"); // 若元素不是有限數字,會拋出錯誤資訊
    }
    return total;
  } else throw new Error("sum(): argument must be array-like"); // 若引數不是類似陣列,會拋出錯誤資訊。
}

型別轉換

JavaScript 可以自動進行類型轉換以適應需要的型別。

  • 以 Boolean 為例:

    1. JavaScript 可將任何型別的值傳給它,並自動執行相應的轉換。
    2. 有些值被稱為 truthy,它們轉換為 true,而其他值被稱為 falsy,它們轉換為false。可參考 JS Comparison Table相等比較 - JavaScript | MDN
  • 以字串為例:

    • JavaScript 會將提供的任何值轉換為字串。
  • 以數字為例

    • JavaScript 會嘗試將提供的值轉換為數字,或者若無法執行有意義的轉換,則轉換為NaN(Not-a-Number)。
console.log(5 + " objects") // "5 objects" 數字10轉為字串
console.log("6" + "20") // 620: 兩個字串都轉成數字
console.log("6" * "6") // 36: 兩個字串都轉成數字
var n = 3 - "a"; 
console.log(n); // NaN: 字串 "a" 不能轉為數字
console.log(n + " object"); // "NaN objects": NaN 轉為字串 'NaN'

參考資料:


結語

  • 由於每天花兩個小時左右閱讀並整理筆記,加上筆記做得有點慢,時間又常常押在當天最後兩個小時,導致沒注意過了12點,就斷賽了 OTZ,明年鐵人賽繼續加油了。
  • 目前寫完了今年30天鐵人賽,後續再重新閱讀,看看這30天筆記中有缺漏的部分,再補上。

上一篇
Day - 29 函式引數- 物件屬性 & 引數型別(一) 筆記
系列文
我的日常學習雜記與筆記整理30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言