|
1 | 1 | # JavaScript30 |
2 | 2 | 30 Day Vanilla JS Challenge |
3 | 3 |
|
| 4 | +## Logs |
4 | 5 | 記錄是為了逼自己天天寫。(? |
5 | 6 |
|
6 | 7 | - Day1 -- 我有寫但放在別台電腦沒commit哈哈 |
|
22 | 23 | - `console.time(name)` + `console.timeEnd(name)` |
23 | 24 | - `console.group(name)` + `console.groupEnd(name)` |
24 | 25 | - Holding down the `Shift`key could be captured by `MouseEvents` and `KeyboardEvents` with `event.shiftKey` (true for holding down shift key) |
25 | | -- Day11 + 12 -- 2017/01/06 |
| 26 | +- Day11 + 12 -- 2017/01/06 |
| 27 | +- Day13 -- PASS (欸) |
| 28 | +- Day14 -- 2017/01/20 |
| 29 | + - 這章好重要,前陣子也有認真看了一下JS裡面`by value`跟`by reference`的問題,另外開一個區塊寫XD |
| 30 | + |
| 31 | +## Notes |
| 32 | +### Day14 - JavaScript References VS Copying |
| 33 | + |
| 34 | +> 記得在stackoverflow上面也有人提出其實JS沒有分所謂的`by value`和`by reference`, |
| 35 | +> 而是以變數的值是否`immutable`的差別來區分, |
| 36 | +> 不過我覺得這樣子的分法對我來說比較好理解。 |
| 37 | +
|
| 38 | +1. By Value (Copying) |
| 39 | + |
| 40 | + 一般來說只要是 strings, numbers 和 booleans,都可以說是 `by value`。 |
| 41 | + |
| 42 | + ```javascript |
| 43 | + let a = "string"; |
| 44 | + let b = a; |
| 45 | + console.log(a, b); // "string", "string" |
| 46 | + b = "another string"; |
| 47 | + console.log(a, b); // "string", "another string" |
| 48 | + ``` |
| 49 | + |
| 50 | +2. By Reference |
| 51 | + |
| 52 | + 如果是 `array` 或者 `object`,則會以 `by reference` 的方式傳遞。 |
| 53 | + |
| 54 | + ```javascript |
| 55 | + let person1 = { |
| 56 | + name: "Trina", |
| 57 | + age: 100, |
| 58 | + gender: "female" |
| 59 | + }; |
| 60 | + let person2 = person1; |
| 61 | + |
| 62 | + console.log(person1, person2); |
| 63 | + //Object {name: "Trina", age: 100, gender: "female"}, Object {name: "Trina", age: 100, gender: "female"} |
| 64 | + |
| 65 | + person2.name = "Sherry"; |
| 66 | + console.log(person2.name); //"Sherry" |
| 67 | + console.log(person1.name); //"Sherry" --> person1 has been changed too! |
| 68 | + ``` |
| 69 | + |
| 70 | + Array 也是一樣的道理: |
| 71 | + |
| 72 | + ```javascript |
| 73 | + let players = ["Trina", "Sherry", "Pisuke", "Kuma"]; |
| 74 | + let team = players; |
| 75 | + console.log(players, team); |
| 76 | + // ["Trina", "Sherry", "Pisuke", "Kuma"], |
| 77 | + // ["Trina", "Sherry", "Pisuke", "Kuma"] |
| 78 | + |
| 79 | + team[3] = "Usagi"; |
| 80 | + console.log(players); |
| 81 | + // ["Trina", "Sherry", "Pisuke", "Usagi"] --> players has been changed too! |
| 82 | + ``` |
| 83 | + 要解決這個問題,就必須把`Object`或`Array`直接Copy一份才行。 |
| 84 | + |
| 85 | + - Copying an array |
| 86 | + |
| 87 | + ```javascript |
| 88 | + //以下幾種方式皆可行 |
| 89 | + const teamCopy1 = players.slice(); |
| 90 | + const teamCopy2 = [].concat(players); |
| 91 | + const teamCopy3 = [...players]; //es6 |
| 92 | + const teamCopy4 = Array.from(players); |
| 93 | + ``` |
| 94 | + - Copying an object |
| 95 | + |
| 96 | + ```javascript |
| 97 | + //以下幾種方式皆可行 |
| 98 | + const personCopy = Object.assign({}, person, { |
| 99 | + newProperty: "some additional property for personCopy" |
| 100 | + }); |
| 101 | + ``` |
| 102 | + 要注意的是以上的方法是 `Shallow copy`,如果 Object 本身是`二維`以上的話,使用上面的方式還是會有 `By reference`的情況發生。 |
| 103 | + |
| 104 | + ```javascript |
| 105 | + let me = { |
| 106 | + name: "Trina", |
| 107 | + age: 24, |
| 108 | + social: { |
| 109 | + twitter: "@tri613", |
| 110 | + github: "tri613" |
| 111 | + } |
| 112 | + }; |
| 113 | + |
| 114 | + let me2 = Object.assign({}, me); |
| 115 | + me2.social.twitter = "@nomoney"; |
| 116 | + |
| 117 | + console.log(me.social); |
| 118 | + //{twitter: "@nomoney", github: "tri613"} --> Changed! |
| 119 | + ``` |
| 120 | + 這種情況需要靠`Deep clone`來解決,最簡單 (但效率表現沒那麼好) 的方式 是直接使用JSON格式encode再decode的方式解決。 |
| 121 | + |
| 122 | + ```javascript |
| 123 | + const meCopy = JSON.parse(JSON.stringify(me)); |
| 124 | + ``` |
| 125 | + 其他的方式可以參考stackoverflow上面的[這篇](http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript)。 |
0 commit comments