iT邦幫忙

2023 iThome 鐵人賽

DAY 16
0
自我挑戰組

一個月的後端學習之旅系列 第 16

【DAY16】擴展語法、剩餘參數、型別轉換

  • 分享至 

  • xImage
  •  

Spread Syntax 用於 array, function invocation

擴展語法 Spread Syntax,允許在需要零個或多個參數argument(例如,function invocation 會需要)或元素(例如,array 的內部元素 )的地方,去擴展 array 內部的元素

myFunction(a, ...iterableObj, b)  // -> iterableObj,可以做迭代的Obj就是iterable
[a, ...iterableObj, b]

//舉例
const parts = ["肩膀", "膝蓋"];
const otherParts = ["頭", ...parts, "身體", "腳"];

console.log(otherParts);  // -> ['頭', '肩膀', '膝蓋', '身體', '腳']
  • 可以複製 array

    const arr = [1, 2, 3];
    const arr2 = [...arr];  // -> ...arr複製出的arr並不是copy by reference
    
    arr2.push(4);
    
    console.log(arr);
    console.log(arr2);
    
  • array concat

    let arr = [1, 2, 3];
    let arr2 = [4, 5, 6];
    
    console.log([...arr, ...arr2]);  // -> [1, 2, 3, 4, 5, 6]
    
  • 在 function 裡擴展

    function sum(x, y, z) {
      return x + y + z;
    }
    
    let arr = [1, 2, 3];
    console.log(sum(...arr));  // -> 6
    
  • 當作部分 argument

    function sum(a, b, c, d, e) {
      return a + b + c + d + e;
    }
    
    let arr = [1, 2, 3];
    console.log(sum(10, ...arr, 5));  // -> 21,a = 10, b, c, d = arr, e = 5
    

Rest Parameters 用於 function definition

收集多個元素並將它們「壓縮」為單個 JS array

function f(a, b, ...theArgs) {
    //...
}

//舉例
function sum(...theArgs) {
  console.log(theArgs);
}
sum(1, 2, 3, 4, 5, 6);  // -> [1, 2, 3, 4, 5, 6]

//把array值全加起來
function sum(...theArgs) {
  let total = 0;
  for (let i = 0, i < theArgs.length; i++){
    total +- theArgs[1];
  }

  return total;
}

console.log(sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));  // -> 55

Data Types

Primitive

string, boolean, number 都是 Primitive Data Type,Primitive Data Type 代表著它們不是Objects,每個 Primitive Data Types 都沒有自己的 attributes 和 methods

此外, 裝有 Primitive Data Types 的 variable 確實擁有數值,而不僅僅是對其數值的記憶體位置的 reference

Reference

Objects, array 都是 Reference Data Type。 Reference Data Type 變數中,儲存的值是 Reference,也就是記憶體的位址,指向儲存真實內容的記憶體區塊的位置

型別轉換 Primitive Coercion

既然 Primitive Data Type 沒有自己的 attributes 和 methods,為何我們使用 string.length 屬性,或是 number.toFixed()這個 method 呢?

當 Primitive Data Type 使用 attributes 和 methods 時,JavaScript 將值自動把數值裝箱到包裝物件 wrapper object中,並改為訪問該 wrapper object 上面的屬性

例如,”foo”.includes(“f”) 會把”foo”放到 new String(“foo”) (Java 創建新的 string 物件),並且執行 new String(“foo”)從 String 繼承而來的 String.prototype.includes()

這種自動裝箱行為在 JavaScript 代碼中是不可觀察

如果一開始在創建 String 的時候,就使用 wrapper object 來製作也可以。但這樣做會造成 RAM 的非必要耗損,且 wrapper object 做物件時間遠較製作 primitive data type 來的更久,code 完成時間會被拖延,所以 MDN 強烈不推薦使用這種寫 code 的方式

//primitive data type
let myName = "Phoebe";

console.log(typeof myName);  // -> string

//wrapper object
let myName = new String("Phoebe");

console.log(typeof myName);  // -> object

測試一下時間

const { performance } = require("perf_hooks"); // node.js

//wrapper object
let startTime = performance.now();

for (let i = 0; i < 10000000; i++) {
  let a = new String("jakdsfjlkajlskdfjaksljfakls;dfja;ls");
}

let endTime = performance.now();
let timeDiff = endTime - startTime;
console.log("一千萬次的String wrapper object製作需要" + timeDiff);  // -> 433.11809998750687毫秒

//primitive data type
startTime = performance.now();
for (let i = 0; i < 10000000; i++) {
  let a = "jakdsfjlkajlskdfjaksljfakls;dfja;ls";
}
endTime = performance.now();
timeDiff = endTime - startTime;
console.log("一千萬次的String宣告需要" + timeDiff);  // -> 13.569000005722046毫秒

下一篇文章學習進階的Array Methods 補充、map forEach比較。


上一篇
【DAY15】Nested loop、Break、Continue、Math Object
下一篇
【DAY17】Array Methods 補充、map forEach比較
系列文
一個月的後端學習之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言