---
# System prepended metadata

title: Javascript
tags: [Javascript]

---

---
title: Javascript
description: 基本知識複習
img: 
alt: 
author:
  name: Jack.hu
  bio: 
  img: 
tags:
  - Javascript
---

# Javascript

### 一、特性

1. 弱型別語言 -> 語法簡潔 -> 易上手
2. 前後端皆可用 **(前端規格參考:ES6，後端NODEJS規格參考:CommonJS)**
3. 除了基本型別之外，萬物皆物件
4. prototype-based，非class-based

### 二、宣告及賦值

#### 宣告

> 需注意scope範圍(function、block)

1. var
2. let & const

#### 基本賦值

1. =

### 三、基本型別(5大型別)

> 型別資訊是在值，而非在變數。

1. string
2. number
3. boolean
4. undefined
5. null

```javascript=
// 為什麼null的型別是object? -> 當初設計時的BUG
typeof null // object

// 注意NaN這個值的型別
typeof NaN // number
```

### 四、物件型別

1. Array
2. Object

### 五、運算子

1. 型別為number，四則運算及比較運算較不會有問題，唯一需注意小數運算會有 **精準度問題**。
2. 型別為string，一些運算操作會導致值會進行 **隱性轉型**，需注意。

#### 四則運算

> 先乘除後加減，同數學運算規則。

1. \+
2. \-
3. \*
4. \/
5. \%(餘數運算)

#### 字串運算

1. \+ 
2. \-
3. \*
4. \/

#### 比較運算

> 進行比較時，會隱性透過原型方法(valueOf、toString)轉成基本型別後才能進行比較。

1. \>
2. \<
3. \==
4. \!=
5. \>=
6. \<=
7. **\===**
8. **\!==**

#### 邏輯運算

> truthy、falsy vs true、false。

> 跟一般程式語言的true&false不太一樣

1. \&&
2. \||
3. \!

```javascript=
let a = 123;
let b = "111";
let c = null;

console.log(a && b);    // 111  注意此例
console.log(a || b);    // 123
console.log(c && a);    // null
console.log(a && c);    // null
console.log(c || a);    // 123

Boolean("false")     // ?
Boolean("0")         // ?
Boolean("''")        // ?
```

#### 位元運算

1. \&
2. \|
3. \^(XOR)
4. \~
5. \>>
6. \<<

#### 三元運算

1. ...? true: false
```javascript=
// 條件? true -> 執行: false -> 執行;
1 === 2? console.log(true):console.log(false); // false
```

#### 其他運算

1. ... in ...

### 六、基本流程

1. if else
2. for
3. while
4. do while
5. switch

### 七、進階流程

1. for of vs for in

### 八、this

1. this會指向定義this所在位置的上層物件。
2. arrow func 沒有this，取決於parent scope的this。

#### 對象

1. function vs () => \{\}
2. constructor func
3. object

### 九、hoisting

1. 宣告變數提升

```javascript=
var x = 1;

var doSomeThing = function(y) {
  console.log(x);   // ？

  var x = 100;
  return x + y;
};

console.log(doSomeThing(50));   // 150
console.log(x);                 // 1

```

2. 宣告函數提升

```javascript=
// case 1
square(2);    // 4

function square(number) {
  return number * number;
}

// case 2
square(2);    // TypeError: square is not a function

var square = function (number) {
  return number * number;
};

```

### 十、Scope Chain

```javascript=
// scope chain 在函數被定義好後就被決定好。
var msg = "global."

function outer() {
  var msg = "local."

  function inner() {
    return msg;
  }

  return inner;
}

var innerFunc = outer();
console.log(innerFunc);
var result = innerFunc();

console.log( result );    //  ?

```

### 十一、Prototype

#### function

1. call, apply
2. bind

#### Obejct

1. valueOf
2. toString


### 十二、sync vs async

#### callback hell

#### Promise(ES6)

#### async and await(ES7)

1. 在迴圈使用上原則上沒問題，但會有些例外，需注意。

### 十三、其他

#### a++ vs ++a

```html=
<h4>++在前</h4>
<script>
    e = ++a + b; // ++a = a+1 = 11 and e = 11 + b = 31 
    document.write("e:", e, "<br />");
    document.write("a:", a, "<br />");
</script>
      
<h4>++在後</h4>
<script>
    f = a++ + b; // f = a + b = 30 and a++ = a + 1 = 11
    document.write("f:", f, "<br />");
    document.write("a:", a, "<br />");
</script>
```

#### RegExp

```javascript=
const multiCondiNotEmptyRegExp = new RegExp('_\\(condi,([0-9]+),([0-9]+),([0-9a-zA-Z -,/\'\.]+)\\)');
/*
 * handles _(condi,start,end,showStr)
 */
function multiCondiNotEmptyFormatter(questions, answers, questionOffset, templateString) {
    let result = templateString;
    console.log("multiCondiNotEmptyFormatter start ===========================\n");
    console.log("result: " + result + "\n");

    while (multiCondiNotEmptyRegExp,test(result)) {
        const [matchedStr, index1, index2, showStr] = multiCondiNotEmptyRegExp.exec(result);
        const start = parseInt(index1, 10) - questionOffset; // 不確定是否為整數型態，先轉換型態。
        const end = parseInt(index2, 10) - questionOffset; // 不確定是否為整數型態，先轉換型態。

        console.log("matchedStr: " + matchedStr + "\n");
        console.log("index1: " + index1 + "\n");
        console.log("index2: " + index2 + "\n");
        console.log("showStr: " + showStr + "\n");
        console.log("start: " + start + "\n");
        console.log("end: " + end + "\n");

        // 思考構想 我想要非連續數的判斷 我不要2-10這種 我要 2,4,6,5
        const answerStart = answers[start];
        console.log('answer: ' + answerStart + '\n');
        console.log(typeof(answerStart));
        console.log(answerStart);
        console.log(answerStart.length);
        // ===========================================
        let numArray = []
        switch (answerStart) {
            for (let i in numArray) {
                case numArray[i]:
                    if (numArray[i].length > 0) {
                        insertTarget = showStr;
                    };
                    break;
            };
        };
        result = _.replace(result, foundLiteral, insertTarget);
    };

    console.log('\n->\n');
    console.log('result: ' + result);
    console.log('\nnotEmptyFormatter end ===========================');
    return result;
}

function locationOrientationFormatter(answers, locationIndex, templateString) {
    console.log(answers);
    console.log("+++++++++++++++++++++++++++++++++++++");
    const locations = answers[locationIndex];
    console.log(locations);
    // assume orientation is the next one
    const orientations = answers[locationIndex + 1];
    console.log(orientations);
    // assume distances is the next one
    const distances = answers[locationIndex + 2];
    console.log(distances);
    // * assume locations and orientations have same length
    
    const result = _.zip(orientations, locations, distances)
        .map(locationSet => `${locationSet[0]} ${locationSet[1]} ${locationSet[2]} cm`);
    return _.replace(templateString, '_(location,orientation)', '<i data-focus="loca">' + grammars.joinWordArray(result) + '</i>');
}

```

---
###### tags: `Javascript`