# Eloquent JavaScript 3rd edition (2018) 第四章~Data Structures: Objects and Arrays
---
tags: Javascript relate
---
###### tags: `Javascript`
> On two occasions I have been asked, ‘Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?’ [...] I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question.
>
> Charles Babbage, Passages from the Life of a Philosopher (1864)
## The weresquirrel
講述一個人有變成松鼠造成他困擾的故事,因此他做了很多個紀錄看看哪些因素導致她變成松鼠,由這個點開啟這個章節的連結。
## Data sets
### array
用來儲存一系列的值,一個值的清單寫在[]這個之間並且使用(,)來區別每個值。
array要取得裡面的值的時候也必須使用[],然後要知道裡面的順序是從0開始,所以當使用
`console.log(listOfNumbers[2]);`的時候是在找array裡面的第三個數字。
```javascript=
let listOfNumbers = [2, 3, 5, 7, 11];
console.log(listOfNumbers[2]);
// → 5
console.log(listOfNumbers[0]);
// → 2
console.log(listOfNumbers[2 - 1]);
// → 3
```
## Properties
String.length 取的字串長度
Max.max 取最大值
這兩個都是expression 取得一些值的屬性。像是我們藉由length這個property來取的myString的value也就是它的長度。
幾乎所有的Js的value都有他的屬性。例外是null and undefined,如果你試著去取的的話會得到error。
``` javascript=
null.length;
// → TypeError: null has no properties
```
然而要訪問property有兩種方式:
第一種就是使用(.)
`value.x`
第二種是使用`[]`
`value[x]`
這兩種方式都可以訪問property但不一定會是一樣的property主要影響的關鍵是其中變數。
* 當使用(.)得時候後方的文字是propery的名子
* 當使用[]的時候在之中的expression被"評估"去取得property
然而當value.x 取得叫做x的value的property的時候
value[x]正在評估那個expression x以及運用它的結果並轉換成字串也就是那個property的名字。
以下以兩個例子可以說明:
* 如果你對color 這個Property有興趣你可以使用 value.color
* 如果你想要擷取property的名字從 binding i 裡面的話你可以使用 value[i]
**在array裡面的元素都被儲存成array的property,並且使用numbers當作property name**
## Methods
> Properties that contain functions are generally called methods
如果propety包含了functions通常你可以叫它們methods
以下程式碼包含了一些範例methods:
push 加上一個值在array的最後面
pop 減去一個值在array的最後面
```javascript=
let sequence = [1, 2, 3];
sequence.push(4);
sequence.push(5);
console.log(sequence);
// → [1, 2, 3, 4, 5]
console.log(sequence.pop());
// → 5
console.log(sequence);
// → [1, 2, 3, 4]
```
## Objects
> Values of the type object are arbitrary collections of properties.
objects 是一種value任意的集合
```javascript=
let day1 = {
squirrel: false,
events: ["work", "touched tree", "pizza", "running"]
};
console.log(day1.squirrel);
// → false
console.log(day1.wolf);
// → undefined
day1.wolf = false;
console.log(day1.wolf);
// → false
```
在property裡面如果不是有效的字串或是數字的話都必須加上("")
```javascript=
let descriptions = {
work: "Went to work",
"touched tree": "Touched a tree"
};
```
如果內容的propety不存在的話會顯示undefine
### delete operator
可以做到刪除property的名字
```javascript=
let anObject = {left: 1, right: 2};
console.log(anObject.left);
// → 1
delete anObject.left;
console.log(anObject.left);
// → undefined
console.log("left" in anObject);
// → false
console.log("right" in anObject);
// → true
```
### in operator
當 `in` operator作用在字串或是objects時,可以告訴你是否這個object有名字
### object.keys
為了得知object的property是什麼可以使用這個function
你給這個function一個object他會return一個array一串也就是property的名字給你
```javascript=
console.log(Object.keys({x: 0, y: 0, z: 2}));
// → ["x", "y", "z"]
```
### Object.assign
可以把別的object的property copy進去
```javascript=
let objectA = {a: 1, b: 2};
Object.assign(objectA, {b: 3, c: 4});
console.log(objectA);
// → {a: 1, b: 3, c: 4}
```
說道這邊可以說出來array就是個object被特化用來儲存一連串的東西。
## Mutability
* string value是沒有辦法改變其內容的
* object value可以被改變 property的內容在不同的時間點
從下方可以得知:O1跟O2的identity相等所以改變時兩個會一起動,然而O3則是雖然一開始的property是一樣的可是他們卻是不一樣的
```javascript=
let object1 = {value: 10};
let object2 = object1;
let object3 = {value: 10};
console.log(object1 == object2);
// → true
console.log(object1 == object3);
// → false
object1.value = 15;
console.log(object2.value);
// → 15
console.log(object3.value);
// → 10
```
就算是const被使用了,object的contents還是可以被改變
```javascript=
const score = {visitors: 0, home: 0};
// This is okay
score.visitors = 1;
// This isn't allowed
score = {visitors: 1, home: 1};
```
## The lycanthrope’s log
解釋了一些關於 correlation,1跟-1代表的意思1代表完全相同,-1代表完全相反,0的話代表不相關
## Computing correlation
這段看不懂但她解釋了


```javascript=
function phi(table) {
return (table[3] * table[0] - table[2] * table[1]) /
Math.sqrt((table[2] + table[3]) *
(table[0] + table[1]) *
(table[1] + table[3]) *
(table[0] + table[2]));
}
console.log(phi([76, 9, 4, 1]));
// → 0.068599434
```
```javascript=
function tableFor(event, journal) {
let table = [0, 0, 0, 0];
for (let i = 0; i < journal.length; i++) {
let entry = journal[i], index = 0;
if (entry.events.includes(event)) index += 1;
if (entry.squirrel) index += 2;
table[index] += 1;
}
return table;
}
console.log(tableFor("pizza", JOURNAL));
// → [76, 9, 4, 1]
```
## Array loops
```javascript=
for (let i = 0; i < JOURNAL.length; i++) {
let entry = JOURNAL[i];
// Do something with entry
}
```
## The final analysis
基本上接續上面也是看不懂
不過檢驗資料的結果是他吃堅果跟他不刷牙導致她變成松鼠。所以她只要不吃堅果就好瞜!~
## Further arrayology
`unshift` and `shift`
在array前方增加或是減少東西
```javascript=
let todoList = [];
function remember(task) {
todoList.push(task);
}
function getTask() {
return todoList.shift();
}
function rememberUrgently(task) {
todoList.unshift(task);
}
```
`remember`
在後方加入新的task
`getTask`
當你準備好要做事情的時候
`rememberUrgently`
在前方加入新的task
`indexOf`
從頭開始尋找特定的value
`lastIndexOf`
從尾開始尋找特定的value
上面兩個methods都可以設定第二個argument當作從哪邊開始搜尋的點
```javascript=
console.log([1, 2, 3, 2, 1].indexOf(2));
// → 1
console.log([1, 2, 3, 2, 1].lastIndexOf(2));
// → 3
```
`slice`
會取得argument中間的數字包含左邊的數字右邊不包含
並且當右邊的argument沒有給的時候會取得後方全部的值,也可以不填寫argument他就會全部array都copy下來
```javascript=
console.log([0, 1, 2, 3, 4].slice(2, 4));
// → [2, 3]
console.log([0, 1, 2, 3, 4].slice(2));
// → [2, 3, 4]
```
`concat`
可以把兩個array黏在一起創造新的array就像 "+"這個operator一樣
`remove`
可以移除指定位置的value
```javascript=
console.log(remove(["a", "b", "c", "d", "e"], 2));
// → ["a", "b", "d", "e"]
```
## Strings and their properties
string number boolean 的value型態都不是objects
所以他們不能這樣使用:
```javascript=
let kim = "Kim";
kim.age = 88;
console.log(kim.age);
// → undefined
```
但他們已經有數個好用的methods了:
```javascript=
console.log("coconuts".slice(4, 7));
// → nut
console.log("coconut".indexOf("u"));
// → 5
```
`trim`
可以消除(spaces, newlines, tabs, and similar characters)
```javascript=
console.log(" okay \n ".trim());
// → okay
```
`padStart`
前方argument代表幾位數後面的代表要加入甚麼數字
```javascript=
console.log(String(6).padStart(3, "0"));
// → 006
```
`split`
`join`
分開句子跟加入東西進去句子
```javascript=
let sentence = "Secretarybirds specialize in stomping";
let words = sentence.split(" ");
console.log(words);
// → ["Secretarybirds", "specialize", "in", "stomping"]
console.log(words.join(". "));
// → Secretarybirds. specialize. in. stomping
```
`repeat`
重複文字內容
```javascript=
console.log("LA".repeat(3));
// → LALALA
```
`length`
探測內文文字長度以及尋找內文定位文字
```javascript=
let string = "abc";
console.log(string.length);
// → 3
console.log(string[1]);
// → b
```
## Rest parameters
(...)的用法,可以把一個array引用進去
```javascript=
let numbers = [5, 1, 7];
console.log(max(...numbers));
// → 7
```
## The Math object
介紹一些math的methods
## Destructuring
如果試著解構dull跟undefined會的到error
## JSON
objects and array都是儲存在電腦的記憶體內,因此它們都有address,如果你想要把他們傳輸給其他電腦做使用,這個時候就需要把它們做序列化serialize 資料,也就是JSON。是一種廣泛運用在網頁資料儲存以及溝通的格式。(其他語言也有在使用)
有一些嚴格的規定存在:
所有property都必須被""包含,並且只能使用簡單的expression並且不能使用functions bindings 或是任何計算甚至註解也不行使用。
```javascript=
{
"squirrel": false,
"events": ["work", "touched tree", "pizza", "running"]
}
```
`JSON.stringify`
回應使用JSON編碼過後的內容回來
`JSON.parse`
擷取出被編譯前的內容出來
```javascript=
let string = JSON.stringify({squirrel: false,
events: ["weekend"]});
console.log(string);
// → {"squirrel":false,"events":["weekend"]}
console.log(JSON.parse(string).events);
// → ["weekend"]
```
## Summary
object 跟 array就像是我們使用一個袋子把東西裝進去並且開始轉動拋,而不是我們直接雙手一開去抓那些東西。
大部分的value都有property,除了null and undefined
array使用numbers當作他property的名字(從0開始)
也有一些像是length這樣property作用在array裡面,他們會作用在property的值上面
也可以使array重複,使用`for (let element of array)`
## Exercises
### The sum of a range
### Reversing an array
### A list
### Deep comparison