最近在上六角學院的js核心篇,將筆記整理出來跟大家分享。
物件與純值
在javascript中只有兩種型別:純值和物件。純值(字串, 數字和布林)無法新增屬性,但物件可以。陣列和函式也是物件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| var string = 'a string'
var newString = new String('a new string')
console.log(string) console.log(newString)
newString.name = 'a name' console.log(newString)
|
newString是使用建構式產生的,此時它就不是純值(字串),而是物件,可以被賦予新的屬性和方法
*陣列也是物件,陣列是物件底下的一種子型別
未定義的物件屬性預設值
若是查找物件下沒有定義過的屬性,會得到undefined的結果,在undefined上無法新增任何屬性。
1 2 3 4 5 6
| var family = { name:'貓貓家' }
console.log(family.dad)
|
物件的參考特性
傳值 vs 傳參考
傳值
person和person2是兩個完全不同的變數,person2只是得到跟person的複製品,其本身與person已無關
1 2 3 4 5 6
| var person = '小花' var person2 = person; person2 = '花花'
console.log(person, person2) console.log(person === person2)
|
傳參考
person和person2這兩個物件共享同一個參考位置,參考位置上的屬性變,共享這個位置的物件的相應屬性也會改變
1 2 3 4 5 6 7 8 9
| var person = { name:'小花' } var person2 = person; person2.name='花花'
console.log(person, person2) console.log(person === person2)
|
純值傳值(布林/數字/字串/undefined/null),物件傳參考(物件/陣列/函式)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| var person = { name:'小花' } var person2 = person;
person2.name={ name:'小花' }
console.log(person, person2) console.log(person === person2)
|
一些觀念練習題:
1 2 3 4 5 6 7
| var x = {x:1} x.y = x;
console.log(x)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| var a = {x:1} var b = a
a.y = a = {x:2}
console.log(a.y) console.log(b) console.log(a === b.y)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| 變數 值 參考位置 var a = {x:1} (0x01) var b = a; (0x01) a.x = {x:2} (0x02)
a.y = a = {y:1}
console.log(a) console.log(b) console.log(b.y === a)
var a = {}; 0x01 var b = a; 0x01
var c = {number:1} 0x02 b = {number:1} 0x02 var c = b = {number:1}; c.name = '小明' console.log(a) console.log(b) console.log(c)
|
Call by Sharing ?
Call by Sharing
以javascript來說,當有多個變數被賦予同個物件時,他們就共享一個參考位置,這就是call by sharing,此時若其中一個物件中的屬性被變動,參考位置上的原始物件內的屬性也會變動,連帶造成其他的物件也都產生相同變化。
淺層 / 深層複製
淺層複製 shallow copy
使用for in
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| var family = { name:'貓貓家', members:{ father:'爸爸貓', mother: '媽媽貓', son:'喵喵貓' } } var newFamily = {};
for(var key in family){ console.log(key); newFamily[key] = family[key]; } newFamily.name = '狗狗家' console.log(family, newFamily) console.log(family === newFamily)
|
要注意的是,這種方法只能複製最外層的物件,也就是family物件,但是內層的members,即使在for迴圈中被複製過去,newFamily和family中的members還是一樣的(因為沒有為它開闢新的記憶體空間)
使用jquery
1
| var newFamily2 = jQuery.extend({}, family)
|
ES6
1
| var newFamily2 = Object.assign({}, family)
|
深層複製
將原物件轉為字串後,讓它失去物件的特性,再parse回來。這樣一來新物件和舊物件會成為完全獨立的物件,裡面的屬性即使包含多少層物件,參考位置也已經完全不同。
1 2 3 4 5 6 7 8 9 10 11 12
| console.log(JSON.stringify(family))
let newFamily = JSON.parse(JSON.stringify(family)) console.log(newFamily === family)
newFamily.members.father = '爸爸狗' console.log(newFamily)
|
陣列
陣列雖然在js中被視為物件,但是取值方式只有使用中括號一種,只能用push方法新增
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| let newArray = [1, 2, 'string', true, { name:'小明' }]
console.log(newArray)
newArray[0]
newArray.push('new value')
newArray.name = '小花'
newArray[10] = '我是第十位' newArray.forEach((item, index) =>{ console.log(`第${index}位`, item) }) console.log(newArray.length)
console.log(newArray[6])
|
JSON
JSON跟物件的不同之處 - 它是獨立於程式語言之外的文字。
JSON是字串,且屬性名稱一定用雙引號撰寫
1 2 3 4 5 6 7 8 9 10
| let example = { property: 'value', }
let jsonExample = JSON.stringify(example)
JSON.parse(jsonExample)
|