owned this note
owned this note
Published
Linked with GitHub
###### tags: `javascript`
# Javascript 學習筆記
適用於會 C++的 JavaScript 新手
## 教材
[w3schools.com](http://www.w3schools.com/js/default.asp)
## 測試環境
- [下載Chrome](https://www.google.com.tw/chrome/browser/features.html) 實際測試
- [Js Bin](http://jsbin.com/?html,output) 線上測試環境
- [Js Fiddle](https://jsfiddle.net/) 線上測試環境
---
# JavaScript Output
- Writing into an alert box, using `window.alert()`.
- Writing into the HTML output using `document.write()`.
- Writing into an HTML element, using `innerHTML`.
- Writing into the browser console, using `console.log()`.
----
輸出的內容,可以是數字、文字(記得加引號)
```javascript=
alert(輸出的內容); //警告視窗
document.write(輸出的內容) //網頁的body裡面
someElement.innerHTML = 輸出的內容 //嵌入html element內容
console.log(輸出的內容) //瀏覽器console
```
---
# JavaScript 命名
小寫開頭的駝峰式命名法為主
---
# JavaScript Operators
----
js有一個三連等號的偵測
偵測型別和值是否相同與不同
equal value and equal
`===`
not equal value or not equal type
`!==`
----
`typeof`
若有`var a`想知道型別,
用`typeof(a)`,物件型別通通只有`object`
```javascript=
typeof("John"); // Returns "string"
typeof(3.14); // Returns "number"
typeof(false); // Returns "boolean"
typeof([1,2,3,4]); // Returns "object"
typeof({name:'John', age:34}); // Returns "object"
typeof(new Date()); // Returns "object"
typeof(function () {}); // Returns "function"
```
使用`a.constructor`抓出建構式的名字比較準
```javascript=
"John".constructor // Returns "function String() { [native code] }"
(3.14).constructor // Returns "function Number() { [native code] }"
false.constructor // Returns "function Boolean() { [native code] }"
[1,2,3,4].constructor // Returns "function Array() { [native code] }"
{name:'John', age:34}.constructor // Returns" function Object() { [native code] }"
new Date().constructor // Returns "function Date() { [native code] }"
function () {}.constructor // Returns "function Function(){ [native code] }"
```
----
`<<`Zero fill left shift
`>>>`~~Zero fill right shift~~ 無符號 右移
`>>`Signed right shift
使用無符號右移,要小心!!!
----
下面使用32位元的數字,比較`>>`和`>>>`的差別
| 算式 | 答案| 算式 | 答案 |
|--:|--:|--|--|
|5>>1| 2| 00...0101 >> 1 | 00...0010
|-5>>1| -3| 10...0101 >> 1 | 10...0011
| 算式 | 答案| 算式 | 答案 |
|--:|--:|--|--|
|5>>>1| 2| 00...0101 >> 1 | 00...0010
|-5>>>1| 2147483645| 10...0101 >> 1 | 1111111111111111111111111111101
---
# JavaScript Data Types
js是動態型別, 宣告的變數可以存放不同的資料型別
剛宣告完的變數,型別預設成`undefine`
----
## Primitive Data
主要型別有這幾種,在function之間使用 call by value
- string
- number
- boolean
- null
- undefined
----
## Complex Data
複雜型別有兩種,在fucntion之間使用 call by value, 只是它的value是reference
- function
- object
----
## null, undefined
剛宣告完的變數,型別預設成`undefine`
`null` 是一個object,沒有建構式
`undefined` 是一個oundefined,沒有建構式
```javascript=
typeof(undefined) //"undefined"
typeof(null) //"object"
null === undefined // false
null == undefined // true
```
----
## 條件賦值
常用情境:
- 預設值
- 避免蓋值的賦值
```javascript=
var a; //undefined
```
```javascript=
var b = a; //maybe undefined
```
```javascript=
var b = a || '0'; //make sure a or zero
```
---
# JavaScript Functions
```javascript=
function myFunction(param1, param2){
if (param1 && param2)
return true;
else
return false;
}
```
----
函數的組成元素
1. 關鍵字`fucntion`
3. 小括號()
5. 大括號{}
2. 函數名稱 (可不寫)
4. 參數 (可不寫)
6. 函數內容 (可不寫)
----
## 參數
其中,參數分成兩個術語`parameters`指的是參數們(那個list), 而`arguments`指的是參數值(變數的內容)
----
## 使用函數的優點
1. reuse code
2. 參數化程式段
----
## 呼叫「定義程式碼」
```javascript=
var a = function(){ return "call me!!"; };
a; //印出function (){return "call me!!"; }
```
## 呼叫「執行程式」
使用()符號進行「呼叫」的動作。XD
```javascript=
var a = function(){ return "call me!!"; };
a(); //印出"call me!!"
```
---
# JavaScript Objects
object = properties + methods
```javascript=
var object = {
properties: "20",
methods: function(){
return true;
}
}
```
----
## get, set 屬性(properties)
```javascript=
object.properties
object["properties"]
```
## get, set 方法(methods)
**回傳function定義**
```javascript=
object.methods
object["methods"]
```
**執行function**
```javascript=
object.methods()
object["methods"]()
```
----
## Do Not Declare Strings, Numbers, and Booleans as Objects!
使程式變複雜,並且降低速度。
基礎型別不使用new運算子,宣告成物件。
---
# JavaScript Scope
Scope is the set of variables you have access to.
**In JavaScript, scope is the set of variables, objects, and functions you have access to.**
----
## 定訂一個Scope
變數生命週期,隨宣告所屬的Scope生命週期決定。
----
`<script></script>` 標籤 是一個Scope,
是windows object的scope
```html=
<script>
//Scope1
</script>
```
函數大括號是一個Scope,
function object的scope
^(是的!這一行沒寫錯!function^ ^object)^
```javascript=
//Scope1
function anyName(){
//Scope2
}
```
----
## 自動宣告全域
不使用`var`宣告,就自動變成全域變數
> Do NOT create global variables unless you intend to.
> In "Strict Mode" automatically global variables will fail.
----
## global scope is the window object.
全域=window 作用域
全域變數=window obj的成員變數
還可以overwrite window obj的成員變數
----
## The Lifetime of JavaScript Variables
The lifetime of a JavaScript variable starts when it is declared.
Local variables are deleted when the function is completed.
Global variables are deleted when you close the page.
----
## 不影響Scope的語法
在`if-else`, `switch-case`, `any loop`裡面宣告的變數,都是「該function」所屬的變數。
```html=
<script>
if (1){
var value = 'a';
}
console.log(value); //a
</script>
```
---
# JavaScript Events
HTML events are "things" that happen to HTML elements.
When JavaScript is used in HTML pages, JavaScript can "react" on these events.
react: 觸發
----
## HTML Events
An HTML event can be something the browser does, or something a user does.
(觸發Html event可以是瀏覽器的任何東西,也可以是使用者)
HTML允許Javascript code寫在event handler屬性裡(要用引號括起來)
```htmlmixed=
<button onclick="document.getElementById('demo').innerHTML = Date()">The time is?</button>
```
當作是這樣
```javascript=
function button_onclick(){
document.getElementById('demo').innerHTML = Date();
}
```
---
# JavaScript Strings
可用單引號,也可以雙引號。
顯示雙引號,字串用單引號。
```javascript=
var str1 = 'I have a "pen".;
```
顯示單引號,字串用雙引號。
```javascript=
var str2 = "I have a 'apple'.";
```
字串相加
```javascript=
var str3 = str1 + str2; //I have a "pen.I have a 'apple'.
```
字串本身可以直接當物件使用
```javascript=
"I have...".length; //9
```
----
## String Length
```javascript=
var txt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var sln = txt.length; //26
```
----
## 跳脫字元的使用
跳脫字元`\`是為了控制typewriters, teletypes, and fax machines,在HTML沒有意義
----
在字串處理還有用的
|code|Output|用chrome試的結果|
|--|--|--|
|`\'`|'|'
|`\"`|"|"
----
這些似乎沒什麼作用了
|code|Output|用chrome試的結果|
|--|--|--|
|`\b`| Backspace(←)|沒反應|
|`\r`| Carriage Return(Enter)|變空格|
|`\f`| Form Feed|沒反應|
|`\t`| Horizontal Tabulator|變空格|
|`\v`| Vertical Tabulator|沒反應|
----
## 字串太長,在程式碼裡斷行
一般javascript的程式碼可以隨意斷行
```javascript=
document.getElementById("demo").innerHTML =
"Hello Dolly.";
```
遇到斷在字串的情況,要加上backslash`\`
```javascript=
document.getElementById("demo").innerHTML = "Hello \
Dolly.";
```
但是也是有變通方法
```javascript=
document.getElementById("demo").innerHTML = "Hello" + "Dolly.";
```
總之不可以合體技(**這樣不行唷!!!!**)
```javascript=
document.getElementById("demo").innerHTML = \
"Hello Dolly.";
```
----
## 字串物件
先說,不要做傻事
```javascript=
var x = "John";
var y = new String("John"); //傻事!!
```
> 它們值一樣,體質不一樣[color=red]
```javascript=
x == y; //true
x ===y; //false
typeof(x); //"string"
typeof(y); //"object"
x.constructor; //function String() { [native code] }
y.constructor; //function String() { [native code] }
x; //"John"
y; //String {0: "J", 1: "o", 2: "h", 3: "n", length: 4, [[PrimitiveValue]]: "John"}
```
```javascript=
var x = new String("John");
var y = new String("John");
x == y //false
```
---
# JavaScript String Methods
所有回傳不同字串的字串方法,都返回新的字串。
技術上來說,字串不能修改,只能替換。
[完整的字串函數](http://www.w3schools.com/jsref/jsref_obj_string.asp)
在此先介紹常用的
----
## 回傳索引值
回傳字串中的index值(`0`起始),找不到回傳`-1`
|function| 意思|
|---|---|
|`indexOf()`|從左邊開始,找字串中的一段字|
|`lastIndexOf()`| 從右邊開始,找字串中的一段字|
| `search()` | 可以吃正規表示式的`indexOf()`<br/>若傳入的是字串,會轉成正規表示式,結果與`indexOf()`相同。|
----
## 回傳新的子字串
|function| 意思|
|---|---|
|`slice(start, end)`|
|`substring(start, end)`|
|`substr(start, length)`|
```javascript=
var str = "Apple, Banana, Kiwi";
```
----
參數
- start, end
- 正數: 左邊開始數
- 負數: 右邊開始數
- length
- 只可以是正數
```javascript=
str.slice(7, 13); //"Banana"
str.slice(-12, -6); //"Banana"
```
----
end若不給,則等同於str.length,start右半邊的字串全部顯示;
```javascript=
str.slice(7); //"Banana, Kiwi"
str.slice(7, str.length); //"Banana, Kiwi"
```
length若不給,則等同於str.length,start右半邊的字串全部顯示;
```javascript=
str.substr(7); //"Banana, Kiwi"
str.substr(7, str.length); //"Banana, Kiwi"
```
```javascript=
str.slice(7, 13); //"Banana"
str.substring(7, 13); //"Banana"
str.substr(7, 13); //"Banana, Kiwi"
str.substr(7, 6); //"Banana"
str.slice(7); //"Banana, Kiwi"
str.substr(7); //"Banana, Kiwi"
```
----
## 回傳替換完的新字串
可使用正規表示式
|function| 意思|
|---|---|
|`replace(findStr, becomeStr)`| 找出findStr, 取代成becomeStr|
----
## 回傳轉成大小寫的新字串
|function| 意思|
|---|---|
|`toUpperCase()`|轉成大寫|
|`toLowerCase()`|轉成小寫|
----
## 回傳組合而成的新字串
|function| 意思|
|---|---|
|`concat(str1, str2, str3)`|以自己本身的字串為開頭,將參數全部組起來|
----
## 回傳指定字元(碼)
這兩個是安全的函數
|function| 意思|
|---|---|
|charAt(position) | 回傳指定索引值的字元 |
|charCodeAt(position) | 回傳指定索引值字元的unicode編碼值 |
這樣做是不安全的
```javascript=
var str = "HELLO WORLD";
str[0]; // returns H
```
如果你要用陣列的方式來處理字串,那就把字串轉態成陣列先。
----
## 回傳指定切割符號,字串變字串傳陣列
這個是安全的函數
|function| 意思|
|---|---|
|split(tokenStr) |在字串找出tokenStr切割字串,回字串傳陣列<br />若tokenStr是空字串,則將每一個字元都切開。 |
---
# JavaScript Numbers
Javascript只有一種數字的資料型別Number,它可以有小數,也可以沒有。
實際的格式是64bit的float(可以說是double)
(遵守[IEEE 754](https://zh.wikipedia.org/wiki/IEEE_754)標準)
|Value (aka Fraction/Mantissa)| Exponent|Sign|
|---|---|---|
|52 bits (0 - 51) | 11 bits (52 - 62)|1 bit (63)
零開頭的數字,會直接略過那些0,不過不要這樣寫。
----
## Precision
- 整數精度: 15位數
- 小數點最大: 17位數(不一定準)
- 小數運算,建議變成整數運算,再回到小數
```javascript=
var x = 0.2 + 0.1; // x will be 0.30000000000000004
var x = (0.2 * 10 + 0.1 * 10) / 10; // x will be 0.3
```
----
## Hexadecimal
數字加了0x就以為自己是16進制了
----
## 轉成其它進制(回傳字串)
數字格式輸出,10進制 only
文字格式輸出,2進制以上,36進制以下。(包含)
```javascript=
var myNumber = 128;
myNumber.toString(16); // returns 80
myNumber.toString(8); // returns 200
myNumber.toString(2); // returns 10000000
```
----
## Infinity
它是一個值,型別是number,有負號。
數字除以0會得到Infinity
```javascript=
Infinity + 2 //Infinity
Infinity - 2 //Infinity
Infinity * 2 //Infinity
Infinity / 2 //Infinity
Infinity % 2 //NaN
Infinity & 2 //0
Infinity | 2 //2
~Infinity //-1
Infinity >> 2 //0
Infinity << 2 //0
Infinity >>> 2 //0
Infinity+"2" //"Infinity2"
```
----
## NaN - Not a Number
它是一個值,型別是number,無負號。
表示數字不是一個合法的數字
----
### 判斷是否是`NaN`
anything丟進全域函數isNaN當參數,就回傳`true`或`false`。無法用`==`或`===`進行判斷。
```javascript=
isNaN(anything);
```
----
### NaN運算
與數字算術運算還是`NaN`
關係運算就不一定了
與字串相加,就把`NaN`當作`"NaN"`
```javascript=
NaN + 2 //NaN
NaN - 2 //NaN
NaN * 2 //NaN
NaN / 2 //NaN
NaN % 2 //NaN
NaN & 2 //0
NaN | 2 //2
~NaN //-1
NaN >> 2 //0
NaN << 2 //0
NaN >>> 2 //0
NaN+"2" //"NaN2"
```
----
## 數字物件
先說,不要做傻事
```javascript=
var x = 123;
var y = new Number(123); //傻事!!
```
> 它們值一樣,體質不一樣[color=red]
```javascript=
x == y; //true
x ===y; //false
typeof(x); //"number"
typeof(y); //"object"
x.constructor; //function Number() { [native code] }
y.constructor; //function Number() { [native code] }
x; //123
y; // |> Number {[[PrimitiveValue]]: 123}
```
```javascript=
var x = new Number(500);
var y = new Number(500);
x == y //false
```
---
# JavaScript Number Methods
`Number`本身無法直接當物件使用。
但是只要宣告、賦值就可以當作物件。(嚴格說起來,資料型別不是`object`)
```javascript=
12.toString(); //Uncaught SyntaxError
var a = 12;
a.toString(); //"12"
(12).toString(); //"12"
```
[完整的數字函數](http://www.w3schools.com/jsref/jsref_obj_number.asp)
在此先介紹常用的
----
## 回傳成字串型態的數字
|function| 意思|
|---|---|
|toString() |數字轉字串 |
----
## 回傳轉指數字串
|function| 意思|
|---|---|
|toExponential() |數字轉指數字串 |
----
## 回傳指定小數後幾位(銀行進位法)
[銀行進位法(Banker's Rounding)](https://zh.wikipedia.org/zh-tw/%E5%A5%87%E9%80%B2%E5%81%B6%E6%8D%A8)缺補0
回傳字串
|function| 意思|
|---|---|
|toFixed() |銀行進位法指定小數點幾位 |
```javascript=
(5.214).toFixed(2); //"5.21"
(5.216).toFixed(2); //"5.22"
```
----
## 指定精確程度(回傳字串包含幾個數字)
四捨五入,缺補0
回傳字串
(`Math.round()`的四捨五入只到整數)
|function| 意思|
|---|---|
|toPrecision() |四捨五入指定數字幾位 |
```javascript=
(5.214).toPrecision(2); //"5.2"
(5.216).toPrecision(2); //"5.22"
```
----
## 回傳它的值
|function| 意思|
|---|---|
|valueOf() |若是數字,就回傳數字 |
看起來似乎沒什麼作用的功能。卻隱藏著重要的作用呀。
有些被宣告成object的number,可以透過這個函數,把值取出來,而且型態是number唷!
----
## 所有的型別都有`valueOf()`和`toString()`
|function| 意思|
|---|---|
|valueOf() |回傳它的本質(number回傳number, string回傳string)|
|toString() |把所有的一切,都化為string|
----
## 回傳Number的全域函數
轉型失敗則會出現NaN
待轉的內容有空白,則就斷掉了(取空白之前的全部)
|function| 意思|
|---|---|
|Number() |把所有的一切,都化為number |
|parseFloat() |把所有空白前的一切,都化為浮點數 |
|parseInt() |把所有空白前的一切,都化為整數 |
----
## "Number"(這個類別)的靜態Property
屬於Number在實作上會用上的一些抽象概念,在此化為符號提供開發者使用。
|Property| 意思|
|---|---|
|MAX_VALUE | js最大值
|MIN_VALUE | js最小值
|NEGATIVE_INFINITY | -∞ (returned on overflow)
|NaN |不是數字
|POSITIVE_INFINITY | ∞ (returned on overflow)
---
# JavaScript Math Object
用來處理一些...數學的問題
[完整的Math用法](http://www.w3schools.com/jsref/jsref_obj_math.asp)
先說常用的
----
## 處理小數點到整數
* x: number即可
|function| 意思|
|---|---|
|Math.round(x)|回傳x四捨五入到整數!!|
|Math.ceil(x)|回傳x無條件進位到整數!!|
|Math.floor(x)|回傳x無條件捨棄到整數!!<br />有點像`parseInt()`和`Math.round()`|
|function| 意思|
|---|---|
|Math.abs(x)|回傳x取絕對值|
|parseInt(x)|數字轉成整數|
----
## 指數對數
|function| 意思|
|---|---|
|Math.pow(x, y) | $x^y$|
|Math.sqrt(x) | $\sqrt{x}$ |
|Math.exp(x) | $e^x$ |
|Math.log(x) | $log(x)$ |
----
## 三角函數
參數使用徑度量
$徑度量 = 度度量\times\frac{π}{180}$
|function| 意思|
|---|---|
|Math.sin(90 * Math.PI / 180) | sin(90°)|
|Math.cos(0 * Math.PI / 180) | sin(0°) |
|Math.tan(x) | tan(x) |
反三角函數
|function| 意思|
|---|---|
|Math.asin(90 * Math.PI / 180) | arcsin(90°)|
|Math.acos(0 * Math.PI / 180) | arcsin(0°) |
|Math.atan(x) | arctan(x) |
----
## 取極值
|function| 意思|
|---|---|
|Math.min(0, 150, 30, 20, -8, -200) | 取最小值(-200)|
|Math.max(0, 150, 30, 20, -8, -200) | 取最大值( 150)|
----
## 取亂數
回傳[0, 1)區間的隨機數
|function| 意思|
|---|---|
|Math.random() | 回傳0(包含)到1(不包含)區間的隨機數字|
----
## 常數
|function| 意思|
|---|---|
| Math.E | 回傳尤拉數([exponential](https://zh.wikipedia.org/zh-tw/E_(%E6%95%B0%E5%AD%A6%E5%B8%B8%E6%95%B0)))小數點後15位<br />2.718281828459045|
|Math.PI|回傳圓週率[π](https://zh.wikipedia.org/wiki/%E5%9C%93%E5%91%A8%E7%8E%87)小數點後15位<br />3.141592653589793|
| Math.SQRT2 | $\sqrt{2}$ = Math.sqrt(2)|
| Math.SQRT1_2 | $\sqrt{1\over2}$ = Math.sqrt(0.5)|
| Math.LOG2E | $log_2(e)$ = Math.log2(Math.E)|
| Math.LOG10E | $log$~10~$(e)$ = Math.log10(Math.E)|
| Math.LN2 | $ln(2)$|
| Math.LN10 | $ln(10)$|
---
# JavaScript Random
`Math.random()`只能取出0~1之間的值(不包含1)。
使用混合技可以取到期望區間中的亂數。
----
## 取整數亂數
取0~(x-1)之間的亂數
```javascript
Math.floor(Math.random() * x)
```
取1~x之間的亂數
```javascript
Math.floor(Math.random() * x) + 1
```
就差在那個+1
----
## 優雅的取亂數的函數
參數: min, max
min(包含)~max(不包含)之間取亂數
```javascript=
function getRndInteger(min, max) {
return Math.floor(Math.random() * (max - min) ) + min;
}
```
min~max(都包含)之間取亂數
```javascript=
function getRndInteger(min, max) {
return Math.floor(Math.random() * (max - min + 1) ) + min;
}
```
就差在那個+1
---
# JavaScript Dates
有了Date就可以用years, months, days, hours, minutes, seconds, and milliseconds
[w3school](http://www.w3schools.com/js/js_date_formats.asp)說
UTC (Universal Time Coordinated) is the same as GMT (Greenwich Mean Time).
[完整的Date用法](http://www.w3schools.com/jsref/jsref_obj_date.asp)
先看常用的
----
## JavaScript Date Formats
使用`Date()`就可以顯示「現在時間」的預設格式
```javascript=
Date(); //Thu Jan 19 2017 16:50:43 GMT+0800 (台北標準時間)
```
顯示預設格式字串
```javascript
Thu Jan 19 2017 16:50:43 GMT+0800 (台北標準時間)
```
顯示成number
```javascript
1484815843956
```
表示距離 January 1, 1970, 00:00:00有幾milliseconds.
----
## 建構式(constructor)
有四種,下面會細說一些變化的用法
```javascript=
new Date() //「現在」的時間物件
new Date(milliseconds)
new Date(dateString)
new Date(year, month, day, hours, minutes, seconds, milliseconds)
```
----
### 使用`new Date(dateString)`
以下的code都會輸出
```javascript=
Tue Oct 14 2014 11:13:00 GMT+0800 (台北標準時間)
```
要用`new Date(...)`, 不可以只是`Date(...)`
```javascript=
new Date("Tue Oct 14 2014 11:13:00 GMT+0800 (台北標準時間)")
new Date("2014-10-14 11:13:00") //國際標準格式
new Date("10/4/2014 11:13:00")
new Date("Oct 14 2014 11:13:00")
new Date("14 Oct 2014 11:13:00") //月日交換
new Date("Tue Oct 14 2014 11:13:00") //星期錯誤會修正
new Date("Tue 14 Oct 2014 11:13:00") //月日交換
```
* 第2行: 這是[國際標準格式(ISO 8601)](https://zh.wikipedia.org/wiki/ISO_8601)
* 第6, 7行: 星期只是參考,會依日期修正。
* 第4~7行: 月份的大小寫、縮不縮寫,都是合法的。
----
### 精確的使用`new Date(dateString)`
```javascript=
new Date(建構子的字串參數 = 日期T時間Z);
```
* T: 區隔日期和時間
* Z: [UTC](https://zh.wikipedia.org/wiki/%E5%8D%8F%E8%B0%83%E4%B8%96%E7%95%8C%E6%97%B6)時間
去掉Z,加上+HH:MM或-HH:MM 指定時區時間
```javascript=
new Date("2014-10-14T11:13:00Z") //Tue Oct 14 2014 19:13:00 GMT+0800 (台北標準時間)
new Date("2014-10-14T11:13:00+08:00") //Tue Oct 14 2014 11:13:00 GMT+0800 (台北標準時間)
```
省略T或Z,不同的瀏覽器,無法預期結果
----
### 指定日期的變化
如果沒有給精確的日期,會依你的時區,有時會有往前一天(月、年)的結果
```javascript=
new Date("2014-10-14"); //介於2014-10-13到2014-10-14之間
new Date("2014-10"); //介於2014-09-30到2014-10-01之間
new Date("2015"); //介於2014-12-31到2015-01-01之間
```
----
### 指定時區
無論讀寫,都會轉成當下瀏覽器的時區。
寫入,可以知道是哪一個時區的使用者寫入。
讀取,使用者永遠不會有時區的問題,因為永遠顯示自己的時區。
----
### WATNINGS!!
先說,不要做下面的傻事!!
> 有些瀏覽器會出問題的做法。(要小心!!)[color=red]
```javascript=
new Date("2015-3-25") //月份的3沒有補0(變成03),有些瀏覽器會回傳"Invalid Date"
new Date("2015/03/25") //"YYYY/MM/DD"是未定義的東西,有些瀏覽器會回傳NaN
new Date("25-03-2015") //"DD-MM-YYYY"是未定義的東西,有些瀏覽器會回傳NaN
```
----
### 使用`new Date(year, month, day, hours, minutes, seconds, milliseconds)`時
```javascript=
new Date(2014, 10, 14, 11, 13, 00); //Fri Nov 14 2014 11:13:00 GMT+0800 (台北標準時間)
```
month要填0-11。
----
## 輸出格式
### 回傳字串顯示
```javascript=
var myDateTime = new Date("2014-10-14 11:13:00");
myDateTime.toString(); //"Tue Oct 14 2014 11:13:00 GMT+0800 (台北標準時間)"
myDateTime.toUTCString(); //"Tue, 14 Oct 2014 03:13:00 GMT"
myDateTime.toDateString(); //"Tue Oct 14 2014"
myDateTime.toTimeString(); //"11:13:00 GMT+0800 (台北標準時間)"
```
---
# JavaScript Date Methods
```javascript=
var myDateTime = new Date("2014-10-14 11:13:00");
//Tue Oct 14 2014 11:13:00 GMT+0800 (台北標準時間)
```
----
## get
Z^+^: 正整數
|Method|定義域|意思|
|---|---|--|
| myDateTime.getDay()|0~6|星期2, 星期日=0
| myDateTime.getMonth()|0~11|9+1月(0起始計數)
| myDateTime.getDate()|1~31|14日
| myDateTime.getFullYear()|Z^+^|2014年
| myDateTime.getHours()|0~23|11時
| myDateTime.getMinutes()|0~59|13分
| myDateTime.getSeconds()|0~59|0秒
| myDateTime.getMilliseconds()|0~999|0毫秒
| myDateTime.getTime()|Z^+^|距1970-01-01以來, 過了1413256380000毫秒
### 可以用一個陣列取出星期的英文
```javascript=
var days = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
days[myDateTime.getDay()] //取得星期幾的英文
```
----
## set
以這個開始`2014-10-14 11:13:00`往下一個一個改變
Z^+^: 正整數
|Method|定義域|意思|
|---|---|--|
| myDateTime.setDate(20)|(1-31)|2014-10-20 11:13:00:000
myDateTime.setFullYear(2015)|Z^+^|2015-10-20 11:13:00:000 (月日填了會改, 可不填)
| myDateTime.setHours(19)|(0-23)|2015-10-20 19:13:00:000
| myDateTime.setMilliseconds(320)|(0-999)| 2015-10-20 19:13:00:320
| myDateTime.setMinutes(52)|(0-59)|2015-10-20 19:52:00:320
| myDateTime.setMonth(7)|(0-11)|2015-07-20 19:52:00:320
| myDateTime.setSeconds(37)|(0-59)|2015-07-20 19:52:37:320
| myDateTime.setTime(0)|Z^+^|1970-01-01 08:00:00:000
----
### 特殊用法
```javascript=
"2014-10-14 11:13:00"
//可以用加天數的方式設定「日」
myDateTime.setDate(myDateTime.getDate() + 6)
//"2014-10-20 11:13:00:000"
//可以填入年月日
myDateTime.setFullYear(2015, 0, 14)
//2015-01-14 11:13:00:000
```
----
### 轉換
時間字串轉`Time()`值
```javascript=
Date.parse("March 21, 2012"); //1332259200000
```
花招!!
```javascript=
var d = new Date(new Date(Date.parse("March 21, 2012")));
//Wed Mar 21 2012 00:00:00 GMT+0800 (台北標準時間)
//等同於下一行
var d = new Date("March 21, 2012");
//Wed Mar 21 2012 00:00:00 GMT+0800 (台北標準時間)
Date.parse("March 21, 2012");
//等同於
var d = new Date("March 21, 2012");
d.getTime();
```
----
## 比較
可以直覺的使用關係運算子。
----
## UTC Date Methods
|Method|Description
|---|---|
|getUTCDate()|Same as `getDate()`, but returns the UTC date|
|getUTCDay()|Same as `getDay()`, but returns the UTC day|
|getUTCFullYear()|Same as `getFullYear()`, but returns the UTC year|
|getUTCHours()|Same as `getHours()`, but returns the UTC hour|
|getUTCMilliseconds()|Same as `getMilliseconds()`, but returns the UTC milliseconds|
|getUTCMinutes()|Same as `getMinutes()`, but returns the UTC minutes|
|getUTCMonth()|Same as `getMonth()`, but returns the UTC month|
|getUTCSeconds()|Same as `getSeconds()`, but returns the UTC seconds|
---
# JavaScript Arrays
Array: 用一個變數儲存多個值
```javascript=
var cars = ["Saab", "Volvo", "BMW"];
var cars = [
"Saab",
"Volvo",
"BMW" //最後的元素後面不要加逗號, 瀏覽器不同,有不同結果
];
```
----
## Creating an Array
直接叫
`var array-name = [item1, item2, ...]; `
```javascript=
var cars = ["Saab", "Volvo", "BMW"];
```
### 陣列物件
不要做傻事!!
> 1. 沒必要 [color=red]
> 2. 速度慢一點點
> 3. 可讀性差一點點
```javascript=
var cars = new Array("Saab", "Volvo", "BMW"); //傻事!!
```
----
## Access the Elements of an Array
### get
```javascript
var name = cars[0];
```
### set
```javascript
cars[0] = "Opel";
```
## 輸出
BJ4
```javascript=
var cars = ["Saab", "Volvo", "BMW"];
document.getElementById("demo").innerHTML = cars; //Saab,Volvo,BMW
document.write(cars); //Saab,Volvo,BMW
window.alert(["Saab", "Volvo", "BMW"]); //Saab,Volvo,BMW
console.log(cars); //["Saab", "Volvo", "BMW"]
```
## Arrays are Objects
Arrays are a special type of objects.
`Array`使用`number`(index)取`elements`
```javascript=
var person = ["John", "Doe", 46];
person[0]; //"John"
```
`Object`使用`string`(name)取`members`
```javascript=
var person = {firstName:"John", lastName:"Doe", age:46};
person["firstName"]; //"John"
```
Array element可以是物件
## Array Properties and Methods
|Property|意思
|--|--|
|.length|Array的長度|
|Method|意思
|--|--|
|.push(x)|添加x到array|
|.sort()|排序element|
### 加入元素
```javascript=
var fruits = ["Banana", "Orange", "Apple", "Mango"];
//除了用
fruits.push("Lemon"); // adds a new element (Lemon) to fruits
//也可以用
fruits[fruits.length] = "Lemon"; // adds a new element (Lemon) to fruits
```
元素插入不連續,中間自動插入`undefined`
```javascript=
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits[fruits.length+1] = "Lemon";
//["Banana", "Orange", "Apple", "Mango", undefined, "Lemon"]
```
Arrays with named indexes are called associative arrays (or hashes).
> 若對array使用了named進行索引,array會變成標準物件。有關array的method也許就無法使用了。
## 判斷是否為Array
1. 用`Array.isArray(arrayObj)`
```javascript=
var fruits = ["Banana", "Orange", "Apple", "Mango"];
Array.isArray(fruits); //true
```
2. 刻一個isArray
```javascript=
function isArray(x) {
return x.constructor.toString().indexOf("Array") > -1;
}
```
3. 用 instanceof
```javascript=
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits instanceof Array //true
```
---
# JavaScript Array Methods
[完整Array看這](http://www.w3schools.com/jsref/jsref_obj_array.asp)
先說常用的
## 陣列變字串
|Method|回傳值|作用|
|-|-|-|
|.toString()|string|element的字串呈現, 用','隔開|
|.join(x)|string|element的字串呈現, 用x隔開|
變回來
```javascript=
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.toString()
//"Banana,Orange,Apple,Mango"
fruits.toString().split(',');
//["Banana", "Orange", "Apple", "Mango"]
fruits.join("+");
//"Banana+Orange+Apple+Mango"
fruits.join("+").split('+');
//["Banana", "Orange", "Apple", "Mango"]
```
JavaScript will automatically convert an array to a string when a primitive value is expected.
```javascript=
document.getElementById("demo").innerHTML = fruits.toString();
document.getElementById("demo").innerHTML = fruits;
```
> All JavaScript objects have a `toString()` method.
## 陣列和元素操作
```javascript=
var fruits = ["Banana", "Orange", "Apple", "Mango"];
```
pop, push, 處理後面的加加減減
shift, unshift, 處理前的加加減減
|Method|回傳值|作用|
|-|-|-|
|fruits.pop()|element|最後element移出陣列, 回傳出來|
|fruits.push(x)|length|添加element進入陣列最後, 回傳它的length值|
|fruits.shift()|element|第一個element移出陣列, 回傳出來|
|fruits.unshift(x)|length|添加element進入陣列第一個, 回傳它的length值|
|fruits[index] = element|element|將element加入指定index位置(0起始計數)|
|delete fruits[x]|bool|將指定index的element換成undefined|
|frults.slice(begin, end)|new Array| 切片<br />包含begin index<br />到end index前一個
### 跟本外掛的`splice()`
一個function可以同時擁有「指定index新增」、「指定index移除」,並且index保持連續。
回傳移除元素的陣列
>用delete則index不連續,會製造undefine [color=red]
```javascript
fruits.splice(startIndex, rmLength, elem1, elem2, ...)
```
從startIndex開始
1. 移除rmLength個element
2. 依序插入新的element
> 執行完 elem1 的 index 就是startIndex
```javascript
var fruits = ["Banana", "Orange", "Apple", "Mango"];
```
|Method|用`splice()`|
|-|-|
|fruits.pop()|fruits.splice(fruits.length-1, 1)
|fruits.push("Penapple")|fruits.splice(fruits.length, 0, "Penapple")
|fruits.shift()|fruits.splice(0, 1)|
|fruits.unshift("Penapple")|fruits.splice(0, 0, "Penapple");|
> Using delete may leave undefined holes in the array.
> Use pop() or shift() instead.[color=red]
```javascript=
var arr = [1, 2, 3];
```
|Method|回傳值|陣列結果|
|-|-|-|
|`arr.pop()`|3|[1, 2]|
|`arr.splice(arr.length-1, 1)`|[3]|[1, 2]
|`arr.push()`|4|[1, 2, 3, 4]|
|`arr.splice(arr.length, 0, 4)`|[]|[1, 2, 3, 4]
|`arr.shift()`|1|[2, 3]|
|`arr.splice(0, 1)`|[1]|[2, 3]
|`arr.unshift()`|4|[4, 1, 2, 3]|
|`arr.splice(0, 0, 4);`|[]|[4, 1, 2, 3]
## 陣列和陣列操作
```javascript=
var myGirls = ["Cecilie", "Lone"];
var myBoys = ["Emil", "Tobias","Linus"];
```
|Method|回傳值|作用|
|---|---|---|
|myBoys.concat(myGirls, ...)|組合之後的Array|將myGirl接到myBody後面, 還可以繼續加|
```javascript=
var myBoys = ["Emil", "Tobias","Linus", ...myGirls];
```
# JavaScript Sorting Arrays
[sort()比較函數要回傳>0, 0, <0](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)
```javascript=
var a = [5, 8, 0, 12, 1, 56, 9, 3, 576, 8];
var b = ["Banana", "Orange", "Apple", "Mango"];
```
正序
```javascript=
a.sort();//[0, 1, 12, 3, 5, 56, 576, 8, 8, 9]
b.sort();//["Apple", "Banana", "Mango", "Orange"]
```
反序
```javascript=
a.reverse();//[9, 8, 8, 576, 56, 5, 3, 12, 1, 0]
b.reverse();//["Orange", "Mango", "Banana", "Apple"]
```
## 數值排序
在`.sort()`的預設行為,是把所有的元素當作字串排序(因為物件會有字串呈現方法)
```javascript=
a.sort(function(a, b){ return a == b;});
a.sort();
```
但是如果要用數字排序,要如何做呢?
```javascript=
b.sort(function(a, b){ return b - a;});//[576, 56, 12, 9, 8, 8, 5, 3, 1, 0]
b.sort(function(a, b){ return a - b;});//[0, 1, 3, 5, 8, 8, 9, 12, 56, 576]
```
> 建議使用`-`而不是用`>`或`<`。
> 原因:
> - 用`-`回傳`>0`, `=0`, `<0`
> - 用`>`或`<`回傳`true`, `false`
>
>[參考資料](http://stackoverflow.com/questions/1063007/how-to-sort-an-array-of-integers-correctly)
## `.sort(`比較函數`)`
比較函數: 自訂排序邏輯
回傳: +, 0 ,-
## 亂數排序
```javascript=
var points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return 0.5 - Math.random()});
```
---
# JavaScript Booleans
[完整的布林值](http://www.w3schools.com/js/js_booleans.asp)
先說常用的
就是`true`和`false`兩個值。
----
## True
```javascript=
Boolean(100); //true
Boolean(3.14); //true
Boolean(-15); //true
Boolean("Hello"); //true
Boolean("false"); //true
Boolean(7 + 1 + 3.14); //true
Boolean(5 < 6); //true
```
----
## False
```javascript=
Boolean(0); //false
Boolean(-0); //false
Boolean(""); //false
Boolean(undefined); //false
Boolean(null); //false
Boolean(false); //false
Boolean(NaN); //false
```
## 布林物件
先說,不要做傻事!!
```javascript=
var x = false;
var y = new Boolean(false); //傻事
var z = new Boolean(false); //傻事again
```
> 它們值相同,體質不同[color=red]
```javascript=
x == y //true
x === y //false
y == z //false
```
# JavaScript Comparison and Logical Operators
混合型別比較 -> 字串變數字
1. 數字字串...就是數字
2. 空字串變0
2. 非數字為NaN
|case|real value|return value|
|-|-|-|
|2 < 12 |2 < 12 |true |
|2 < "12" |2 < 12 |true |
|2 < "John" |2 < NaN |false|
|2 > "John" |2 > NaN |false|
|2 == "John"|2 == NaN|false|
|"2" < "12" |2 < 1 |false|
|"2" > "12" |2 > 1 |true |
|"2" == "12"|2 == 12 |false|
數字的字串比較,會比第一位。
比較之前,先檢查型別,是一個很好的習慣唷!
---
# JavaScript For Loop
- for - 已知執行次數的重複程式碼
- for/in - 走訪obj/list的每一個元素
- while - 依條件決定是否要繼續執行的重複程式碼
- do/while - 先執行一次重複程式碼,再判斷是否要繼續執行
## The For/In Loop
```javascript=
var person = {fname:"John", lname:"Doe", age:25};
//var person = ["John", "Doe", 25]; //這樣宣告,結果一樣
var text = "";
var x;
for (x in person) {
text += person[x];
}
```
兩段程式的結果
```javascript
text = "JohnDoe25"
```
---
# JavaScript Break and Continue
`break`和`continue`和C語言用法一樣。
`break`有個地方滿特別的,就是配合`Label`可以指定跳脫區段
只是很少用就是了!^^
```javascript=
var cars = ["BMW", "Volvo", "Saab", "Ford"];
list: {
console.log(cars[0]);
console.log(cars[1]);
console.log(cars[2]);
break list;
console.log(cars[3]);
console.log(cars[4]);
console.log(cars[5]);
}
```
---
# JavaScript Type Conversion
- Number() converts to a Number
- String() converts to a String
- Boolean() converts to a Boolean
```graphviz
digraph hierarchy {
not_value->undefined
value->string
value->bool
value->number
value->object
value->function
number->NaN
number->Infinity
object->array
object->date
object->null
}
```
```javascript=
function isArray(myArray) {
//找Array這個字
return myArray.constructor.toString().indexOf("Array") > -1;
}
function isDate(myDate) {
//找Date這個字
return myDate.constructor.toString().indexOf("Date") > -1;
}
```
## JavaScript Type Conversion
任意變數可以轉成任何一個新的變數+型態,兩種方法
1. 用function轉
2. Js自動轉
### function轉
| Method | Descript |
|-|-|
|string = String(number)<br/>string = number.ToString()| Numbers to Strings|
|string = String(bool)<br/>string = bool.ToString()| Booleans to Strings|
|string = String(Date())<br/>string = Date().ToString()|Dates to Strings|
|number = Number(string)<br />number = parseFloat(string)<br />number = parseInt(string)|Strings to Numbers|
|number = Number(bool)|Booleans to Numbers|
|number = Number(date)<br />number = date.getTime()|Dates to Numbers|
### 自動轉數字
| Method | Descript |
|-|-|
|y = + "3" | 直接加正負號轉數字 |
### 運算自動轉
混合型別的運算
| Method | Descript | result type |
|-|-|-|
|"5null" = "5" + null | "5" + "null"|string|
|52 = "5" + 2 | "5" + "2"|string|
|5 = 5 + null | 5 + 0| number|
|3 = "5" - 2 | 5 - 2|number|
|10 = "5" * "2" | 5 * 2|number|
### 顯示到HTML自動轉string
```javascript=
document.getElementById("demo").innerHTML = myVar;
// if myVar = {name:"Fjohn"} //"[object Object]"
// if myVar = [1,2,3,4] //"1,2,3,4"
// if myVar = new Date() //"Fri Jul 18 2014 09:08:55 GMT+0200"
// if myVar = 123 //"123"
// if myVar = true //"true"
// if myVar = false //"false"
```
## Converted to Number
```graphviz
digraph hierarchy {
false->0
0->0
str_0->0
str_000->0
null->0
str_空的->0
List_空的->0
}
```
```graphviz
digraph hierarchy {
NaN->NaN
undefined->NaN
str_twenty->NaN
function_空的->NaN
object_空的->NaN
List_10_20->NaN
List_twenty->NaN
}
```
```graphviz
digraph hierarchy {
true->1
1->1
str_1->1
Infinity->Infinity
負Infinity->負Infinity
str_20->20
List_20->20
}
```
## Converted to String
```graphviz
digraph hierarchy {
str_twenty->str_twenty
List_twenty->str_twenty
str_20->str_20
List_20->str_20
1->str_1
str_1->str_1
0->str_0
str_0->str_0
str_000->str_000
str_空的->str_空的
List_空的->str_空的
}
```
```graphviz
digraph hierarchy {
false->str_false
true->str_true
NaN->str_NaN
Infinity->str_Infinity
負Infinity->str_負Infinity
}
```
```graphviz
digraph hierarchy {
null->str_null
undefined->str_undefined
List_10_20->str_List_10_20
function_空的->str_function_空的
object_空的->str_object_Object
}
```
---
# JavaScript Bitwise Operators
10 to 2
```javascript=
function dec2bin(dec){
return (dec >>> 0).toString(2);
}
```
2 to 10
```javascript=
function bin2dec(bin){
return parseInt(bin, 2).toString(10);
}
```
# JavaScript Regular Expressions
正規表示式!!
[完整版](http://www.w3schools.com/jsref/jsref_obj_regexp.asp)看這
先看常用的
[線上產生器](http://macloudlab.tw/wp/sampleFiles/RegExp/)
## 語法
```javascript=
/pattern/modifiers;
```
例子:
```javascript=
var patt = /w3schools/i;
```
- `/w3schools/i` is a regular expression.
- `w3schools` 關鍵字
- `i` 大小寫視為相同
## 用途
它是用於`text search`和`text replace`的`search pattern`
有三個要知道的事。
1. `text search`
1. `text replace`
1. `search pattern`
### search和replace
常使用的兩個string meghods: `search()`, `replace()`
`search()`: 回傳找到符合條件的字串開頭索引值
`replace()`: 回傳修替換改後的字串
正規表示式的查詢,不分大小寫。
**字串查詢**
`search()`
```javascript=
var str = "Visit W3Schools";
var n = str.search(/w3schools/i);
var str = "Visit W3Schools!";
var n = str.search("W3Schools");
//n = 6
```
**字串替換**
`replace()`
```javascript=
var str = "Visit Microsoft!";
var res = str.replace(/microsoft/i, "W3Schools");
var str = "Visit Microsoft!";
var res = str.replace("Microsoft", "W3Schools");
//res = Visit W3Schools!
```
### search pattern
(往下看就知道了)
## Regular Expression Modifiers
|Modifier|| 功能描述|
|-|-|-|
|i|insensitively |有加`i`: 大小寫視為相同<br />沒加`i`: 大小寫視為不同|
|g|globally|有加`g`: 找完才停(找everyone)<br />沒加`g`: 找到就停(找anyone)|
|m|跨越換行符號|多行??|
## Regular Expression Patterns
有三種
1. `Brackets` []夾起來的部份, 指定查詢範圍
1. `Metacharacters` \加上字母描述, 描述指定字元
1. `Quantifiers`符合次數,(+ * ?)
### `Brackets`
`Brackets` 查詢字元的範圍:
|Expression| 功能描述|
|-|-|
|[abc]| 找英文字元,在此例,要找符合abc三個字母,其中一個即可|
|[0-9]| 找數字字元,在此例,要找符合0~9範圍內容,其中一個即可|
|(x\|y)| 同時找兩個條件,在此例找符合x或y,其中一個即可|
### `Metacharacters`
`Metacharacters` 查詢指定字元:
|Metacharacter| 功能描述|
|-|-|
|\d|digit 數字字元<br />等價於`[0-9]`|
|\s|space 空白字元<br />包括writespace、tab、enter等等。等價於`[ \f\n\r\t\v]`。|
|\b|boundary 邊界位置<br />「er\b」可以符合「never」中的「er」,但不能符合「verb」中的「er」。|
|\uxxxx|指定unicecode的編碼字元, 用xxxx四位的十六進制表示|
- `/t`是水平tab, `/v`是垂直tab, 中國翻譯成製表符
- `/f`換頁符`ctrl + enter`, `/n`換行符`enter`
### `Quantifiers`
`Quantifiers` 定義查詢次數:
|Quantifier| 功能描述|
|-|-|
|n+|可以出現零次或多次。<br />「`goo+gle`」可以符合google、gooogle、goooogle等|
|n?|最多只可以出現一次。<br />「`colou?r`」可以符合color或者colour|
|n\* |可以出現零次或一次或者多次。<br />「`0*42`」可以符合42、042、0042、00042|
## Using the RegExp Object
|Method| Descript|
|-|-|
|regex.test(x)|測試目前的pattern是否可以在x找到東西|
### `regex.test()`
測試`str.search(regex)`是否查詢得到任何內容
```javascript=
var str = "The best things in life are free!";
str.search(/e/); //return 2
```
若上面的`str.search()`回傳`-1`,則下面的`test()`就會回傳`false`
反之`str.search()`回傳不是`-1`,則下面的`test()`就會回傳`true`
```javascript=
var patt = /e/;
patt.test("The best things in life are free!"); //return true
```
也可以寫成
```javascript=
/e/.test("The best things in life are free!"); //return true
```
### ` regex.exec()`
執行`str.search(regex)`查詢到的(第一個)內容
用Chrome執行回傳Array但是在網路教學是給字串
(不過它的sample code是顯示到頁面上`["e"]`會轉成`e`沒錯)
```javascript=
/e/.exec("The best things in life are free!");
//return ["e"]
```
# JavaScript Errors - Throw and Try to Catch
![](https://i.imgur.com/NK1tcBh.png)
紅色的字,第一行是這樣組成的 `Uncaught error.name: error message`
## The Error Object
- Property
- name
- **EvalError**
使用`eval()`產生的錯誤
新版的Javascript將用`SyntaxError`取代這個
- **RangeError**
數字超出範圍的錯誤(定義域出錯)
- **ReferenceError**
非法引用的錯誤(使用未宣告、定義的變數、物件或function)
- **SyntaxError**
語法寫錯了
- **TypeError**
型別出錯(物件沒有這個`method()`)
- **URIError**
使用`encodeURI()`產生的錯誤
- message
> `eval()`絕對不會拋錯,只要`eval()`出錯,一定是Syntax出錯。[color=red]
## Non-Standard Error Object Properties
這些就當作方便開發用的屬性就好!上線的網站不要使用這些東西。
**Mozilla**
err.fileName
err.lineNumber
err.columnNumber
err.stack
**Microsoft**
err.description
err.number
# JavaScript Debugging
> Errors can (will) happen, every time you write some new computer code.
- The console.log() Method
- Setting Breakpoints
- The debugger Keyword
- 在一般執行的情況之下,等同於下了一個中斷點
- 若已經debugging,則此關鍵字會失去作用
> 世界第一隻bug,是卡在電路上的昆蟲
> 不是人造物,人類思緒缺陷的產物
# JavaScript Hoisting
`Hoisting`的意思就是不管你寫在哪,預設就是優先執行宣告的程式碼
- Hoisting
- Declarations
- Not Hoisted
- Initializations
## Declare Your Variables At the Top !
> JavaScript in strict mode does not allow variables to be used if they are not declared.
Study "use strict" in the next chapter.[color=red]
# JavaScript Use Strict
`"use strict";`Defines that JavaScript code should be executed in "strict mode".
:::info
定義
- 進入strict mode, 就無法宣告新的全域變數
(`window`的成員變數)
- strict mode會在作用域結束時解除
:::
**使用方式**
宣告`"use strict";`
:::warning
1. 在Chrome的console直接輸入,是沒有受限制的
2. 最好寫在js文件或function開頭!!
:::
## Why Strict Mode?
- 錯誤語法變成`ERROR`
- 降低容錯
- 八進制 ~~010=8~~
- 字元碼 ~~'\010=(空白)'~~
- 禁止「隱性宣告全域變數」(不加var)
- 安全性較高,不會因為打錯字,新增了新的全域變數
### 一般情況
```javascript=
"use strict";
x1 = 3.14; //錯誤語法,要加var
function x3(p1, p1) {}; //錯誤語法,重複的參數名稱p1
function x4(p1, p2) {};
delete x4; //錯誤語法,刪除function name
var x5 = 010; //錯誤語法,零開頭的十進制(無八進制)
var x6 = '\010' //錯誤語法,字元碼
```
### 物件
```javascript=
"use strict";
x1 = {p1:10, p2:20}; //錯誤語法,要加var
var x2 = {};
Object.defineProperty(x2, "x", {value:0, writable:false});
x2.x = 3.14; //錯誤語法,唯讀屬性不可寫
var x3 = {get x() {return 0} };
x3.x = 3.14; //錯誤語法,唯讀屬性不可寫
```
### 關鍵字
ES6 的保留關鍵字也是不可以使用的
```javascript=
"use strict";
delete Object.prototype; //錯誤語法,刪除不可刪除的屬性
var eval = 3.14; //eval是關鍵字
var arguments = 3.14; //arguments是關鍵字
with (Math){x = cos(2)}; // 不能用with
eval ("var x = 2");
alert (x); //For security, 不可以呼叫在eval()宣告的變數
```
# JavaScript Common Mistakes
[Javascript 問答集](https://hackmd.io/MYTgHATAJghhDMBaAbGA7BRAWNaBmiARjFmImoWHpAKyoCm8EQA=)
# JavaScript Performance
## 避免不必要的變數
slow
```javascript=
var fullName = firstName + " " + lastName;
document.getElementById("demo").innerHTML = fullName;
```
fast
```javascript=
document.getElementById("demo").innerHTML = firstName + " " + lastName
```
## 減少 Loops 裡的動作
雖然與上一個抵觸,在此把loop視為特例
slow
```javascript=
var i;
for (i = 0; i < arr.length; i++) {
```
fast
```javascript=
var i;
var l = arr.length;
for (i = 0; i < l; i++) {
```
## 減少 DOM 存取次數
之後會再存取,就先存成變數。
## 減少 DOM 的大小
(用JS長樹?)
## 延遲載入 JavaScript 檔案
放在`<body>`末端,有助於文件載完再跑JS
如果可以,可以用下面的方法載入JS,而且一定能確保文件載入 完畢才載入JS
```htmlmixed=
<script>
window.onload = function() {
var element = document.createElement("script");
element.src = "myScript.js";
document.body.appendChild(element);
};
</script>
```
## 避免使用 `with`
with對執行速度有負面影響。
It also clutters up JavaScript scopes.
> strict mode 禁止使用
# JavaScript JSON
深入學習看[JSON tutorial](https://www.w3schools.com/js/js_json_intro.asp)
**What is JSON**
JSON是一種傳輸/儲存格式
通常用在server to client
**Define**
JSON = *J*ava*S*cript *O*bject *N*otation JS物件表示法
JSON = 輕量級數據交換格式 (重量級=XML)
JSON = 跨語言
JSON = 文件
它是JavaScript物件表示法的字串!!可用任何語言生成
**語法規範(JSON Syntax Rules)**
- pair = `"`key`": `value (key要加雙引號!!)
- data = pair`, `pair
- objects = `{ `data` }`
- arrays = `[`value, value`]`
## string to JSON
```
var json_obj = JSON.parse(str);
```
## Object
### constructor
```javascript=
var a = new J();
var a = Object.create(J);
```
使用 new 後面接一個函數時,
會建立一個空物件,接著執行這個函數
並將函數執行環境的 this 指向這個空物件
利用 this 來增加物件的屬性
最後不需使用 return,JS會自動回傳這個物件