今日任務: 認識JavaScript 的參數傳遞
JavaScript 是弱型別,也能說是動態的程式語言。這代表你不必特別宣告變數的型別。程式在運作時,型別會自動轉換。這也代表你可以以不同的型別使用同一個變數。
var foo = 42; // foo 目前是數字
var foo = 'bar'; // foo 目前是字串
var foo = true; // foo 目前是布林值
最新的 ECMAScript 標準定義了七種資料型別:
在JS中,原始型別都是使用傳值(By Value)
當a指定為原始型別,會在記憶體中存一個自己的位置(假設叫做0x001)
指定b的值等於a(b=a)時,
b也會在記憶體中存一個自己的位置(假設叫做0x002),再複製一份a的值存在裡面
稱之為傳值(By Value)
所以a 和 b 存在於兩個不同的記憶體位置,兩個不會互相影響
舉例: 字串、數字
let a = 10;
let b = age;
console.log(a, b);
b = 20;
console.log(a, b);
let name = 'Sarah';
let name2 = name;
console.log(name, name2);
name2 = 'Ryan';
console.log(name, name2);
在JS中,物件型別都是使用傳址(By Reference)
當a指定為物件型別,會在記憶體中存一個自己的位置(假設叫做0x001)
指定b的值等於a(b=a)時,
b會直接指定到a記憶體的位置(0x001)
稱之為傳址(By Reference)
所以a 和 b 兩個會互相影響,a改變b也會跟著改變,反之亦然
舉例:陣列
const players = ['Wes', 'Sarah', 'Ryan', 'Poppy'];
// and we want to make a copy of it.
const teams = players;
console.log(players, teams);
teams[2] = 'Jim';
//players和teams都被改變
console.log(players, teams);
會回傳一個新陣列物件,為原陣列選擇之 begin 至 end(不含 end)部分的淺拷貝(shallow copy)。而原本的陣列將不會被修改。
const team2 = players.slice();
team2[3] = 'Tom';
concat 是英文 concatenate 的縮寫,意思是串接(link things together in a chain or series.)
const team3 = [].concat(players);
team3[3] = 'Tom3';
const team4 = [...players];
team4[3] = 'ES6';
const team5 = Array.from(players);
team5[3] = 'Array.from';
舉例:物件
除了陣列,物件也一樣
const person = {
name: 'Wes Bos',
age: 80,
};
const captain = person;
captain.number = 99;
console.log('person', person);
console.log('captain', captain);
用來複製一個或多個物件(obj1,obj2,...)到target,。回傳的值為target。fruit: 'apple'
會直接加進去,age:12
會直接覆蓋過去
const captain2 = Object.assign({}, person, { fruit: 'apple', age: 12 });
const captain3 = { ...person };
captain3.number = 111;
以上都是淺層的copy,深層的還是會被改變
const wes = {
name: 'Wes',
age: 100,
social: {
twitter: '@wesbos',
facebook: 'wesbos.developer',
},
};
const dev = Object.assign({}, wes);
dev.age = 50;
dev.social.twitter = '@asdf111';
console.log('wes', wes);
console.log('dev', dev);
可以發現只有第一層沒有跟著連動,第二層資料還是一起被改變了
以上複製方法都是淺拷貝,也就是只有第一層複製了,但是深層的還是共用一個記憶體
那要怎麼完整的複製,讓兩個指向完全不同的記憶體呢?
1.先轉成字串,不再是物件JSON.stringify()
:將JavaScript 值轉換為 JSON 字符串
const dev2 = JSON.stringify(wes);
2.再把他轉回物件JSON.parse()
: 將JSON 字串轉換成 JavaScript 的數值或是物件
const dev2 = JSON.parse(JSON.stringify(wes));
dev2.age = 30;
dev2.social.twitter = '@zxc222';
console.log('wes', wes);
console.log('dev2', dev2);
今日學習到的:
效果連結:連結
參考連結:
MDN: JavaScript 的資料型別與資料結構
Fooish 程式技術: JavaScript 資料型態 (Data Types)
Object references and copying
PJCHENder :談談 JavaScript 中 by reference 和 by value 的重要觀念
MDN: slice()
MDN: Object.assign({}, obj)
MDN: JSON.parse()
MDN: JSON.stringify()