在前幾天的課題當中,我們開始接觸到資料的使用,在今天的課題當中,我們要來認識 javascript 中各種資料型別,以及其在使用上要注意的事項。[1]
JavaScript 是一种弱類型
或者動態語言
。代表我們今天我們在創造一個變數的時候,不需要先宣告變數的資料類型,他會在程式運作的過程中自動被定義類型。[2]
而在 javascript 程式語言中,總共含有七種資料型別,其中又可以分成簡單型別與複雜型別。[3]
String
Number
Boolean
Null
Undefined
Symbol (ECMAScript 6 新定義)
Object
是唯一的複雜資料型別。而 Object
、 Array
、 Function
都屬於Object的複雜資料型別。當我們宣告一個變數時,不同的資料型別將會以不同的方法在記憶體中建立這筆資料。[4]
let a = true;
let b = a;
b = false;
console.log(a); //true
console.log(b); //false
let a = [true];
let b = a;
b[0] = false;
console.log(a); //[false]
console.log(b); //[false]
了解不同資料型別之間 By Value
與 By Reference
的差異之後,我們可以開始今天的題目:
Start with strings, numbers and booleans.
let name = 'Kevin';
let age = 27;
let handsome = true;
let copyName = name;
let copyAge = age;
let copyFace = handsome;
console.log('Name:', name, copyName);
console.log('Age:', age, copyAge);
console.log('Handsome:', handsome, copyFace);
後續加上以下的 code 之後再 console.log 一次,會發現 Kevin 系列就會如同前面所提的 by Value 模式,維持一樣的資料內容:
copyName = 'OTree';
copyAge = 100;
copyFace = false;
Let's say we have an array.
let players = ['Andy', 'Bosh', 'Chris', 'David'];
let copyPlayers = players;
console.log('team1:', players);
console.log('team2:', copyPlayers);
後續加上以下的 code 之後再 console.log 一次,會發現 team1 陣列內容就會如同前面所提的 by reference 模式隨著 team2 改變而被改變:
copyPlayers[1] = 'Ben';
copyPlayers[3] = 'Dick';
從以上的結果來看,如果我們今天需要複製一個陣列,並修改複製出來的陣列內容,應該要怎麼做呢?
我們可以透過會建立一個新的陣列的方法,來複製原始陣列,如此一來我們就可以對複製出來的陣列為所欲為,且不會對原始陣列造成傷害:
slice()
: 擷取陣列中的某一段成為新的陣列。let players = ['Andy', 'Bosh', 'Chris', 'David'];
let copyPlayers = players.slice();
copyPlayers[1] = 'Ben';
copyPlayers[3] = 'Dick';
console.log('team1:', players);
console.log('team2:', copyPlayers);
concat()
:回傳一個包含呼叫者陣列本身的值,以及被當作參數提供的陣列或是值的而成的新陣列。let players = ['Andy', 'Bosh', 'Chris', 'David'];
let copyPlayers = [].concat(players);
copyPlayers[1] = 'Ben';
copyPlayers[3] = 'Dick';
console.log('team1:', players);
console.log('team2:', copyPlayers);
Array.from()
:會從類陣列(array-like)或是可迭代的物件建立一個新的陣列。let players = ['Andy', 'Bosh', 'Chris', 'David'];
let copyPlayers = Array.from(players);
copyPlayers[1] = 'Ben';
copyPlayers[3] = 'Dick';
console.log('team1:', players);
console.log('team2:', copyPlayers);
以上的方法都可以建立一個新的陣列,印出來的內容如下,而其他還有許許多多方法可以利用,大家可以嘗試適合自己的方法。
with Objects.
let Kevin = {
name: 'Kevin',
age: 27
};
let copyKevin = Kevin;
console.log(Kevin);
console.log(copyKevin);
後續加上以下的 code 之後再 console.log 一次,會發現 Kevin 以及 copyKevin 物件內容被一同改變:
copyKevin['name']='OTree';
copyKevin['age']=100;
在這邊我們一樣可以利用會建立新物件的 object.assign()
方法,來複製原始物件,如此一來就不會更動到原始物件內的屬性:
let Kevin = {
name: 'Kevin',
age: 27
};
let copyKevin = Object.assign({}, Kevin);
copyKevin['name']='OTree';
copyKevin['age']=100;
console.log(Kevin);
console.log(copyKevin);
但如果今天我們的物件中又包了一個物件,我們就必須使用深層複製,否則內層物件中的屬性,還是會一樣指到相同的位置:
JSON.parse(JSON.stringify(object));
淺層
let Kevin = {
address:{
city:'Tainan'
}
};
let copyKevin = Object.assign({}, Kevin);
copyKevin['address']['city']='Yunlin';
console.log(Kevin);
console.log(copyKevin);
深層
let Kevin = {
address:{
city:'Tainan'
}
};
let copyKevin = JSON.parse(JSON.stringify(Kevin));
copyKevin['address']['city']='Yunlin';
console.log(Kevin);
console.log(copyKevin);
今天學習到以下的東西:
By Value
以及 By Reference
變數資料的差異。在今天的課題中,我們了解到不同的變數資料型別在使用時可能會遇到的地雷,以及該如何解決的方法,讓我們在使用或修改變數資料的時候可以更加安穩。
以上是今天的方法與心得,感謝您的閱讀。