---
# System prepended metadata

title: Javascript language go through
tags: [javascript]

---

# Javascript language go through
[toc]
## 1. 觀念篇
### 1.1 學習程式語言，你需要的核心觀念是...
**了解，而不只是模仿**

### 1.2 重要觀念一:Javascript執行環境
- Syntax Parser: 將code轉成電腦懂的東西
- Lexical Environment: code在程式碼的實際位置
- Execution Context: 管理正在執行的程式
### 1.3 重要觀念二
- Object in javascript: A collection of name/value pairs
- Global Execution Context: Not in a function 

### 1.4 Global Execution Context:
    
- create global object
- create **this**
- Linking to outer Environment

### 1.5 Javascript hoisting
    Javascript會為使用到的函數先弄到記憶體，無關它在程式碼的位置，因此可以在定義函數之前或是之後去呼叫函數
### 1.6 Javascript and undefined
    undefined是javascript裡面的特殊關鍵字，用來表示變數還未被定義，也是變數宣告未被設定值時的預設值。(也可以說是值not set)
## 2. 名詞解釋
### 2.1 Single thread
one command at a time

### 2.2 Synchronous execution
one at at time

### 2.3 Javascript語言特性
Javascript is single thread and synchronous execution

### 2.4 Function invocation in Javascript
call the function，每當一個新的function被invocate，就會創一個新的Execution Context，並被排入Context Stack

### 2.5 Variable Environment in Javascript
變數所存在的環境，每個Execution Context都可以有自己的變數，不同的execution context裡面的變數互不相關

### 2.6 Scope chain
the reference of outer environment，這牽扯到lexical environment，當函數裡的變數找不到時，javascript會去找上一層包含函數的execution context內有沒有，這個尋找的連結就是scope chain

### 2.7 Scope
變數可以被使用的範圍

關鍵字：let

## 2.8 Asynchronous callbacks
more than one at a time
- javascript engine: engine內部本身是synchronous
但是會有一個Event queue，當javascript engine裡面處理完一個Event後，才會輪到下一個Event，內部javascript engine而言，他就是synchronous，等到execution context是空的才會輪到下一個event。
因此Asynchronous的部份會交給javascript engine外的部份去完成。
## 3. Javascript語言本身
### 3.1 Javascript and its types
- dynamic typing: 在執行時才知道型別
- Primitive types: a single value
    - undefined(default value of a var)
    - null: 表示一個變數值不存在
    - boolean: true/false
    - number: 2, 3, 5.2...
    - string: "this is string"
    - symbol: using ES6, not applied yet
- coercion: 強制轉型

### 3.2 Javascript and its operator
- operator is a special function for operands to get a value

### 3.3 Framework & Library
- default value: 當把所有js file會彙整成，因此不讓js file中的變數名稱彼此衝突是一件重要的事。
- namespace: a container for variables and functions, javascript does not have it, but can fake it. use object to fake it

### 3.4 Objects and Functions
- Objects: name/value pairs，物件裡可以有純值(屬性)/物件(屬性)/函數(方法)
- Object literal: 使用{}去建立name:value pair

### 3.5 JSON and object literal
- JSON: Javascript Object Notation: 和Object的語法不同的是，Name一定要有雙括號，JSON並不存在function object。

### 3.6 Functions are Objects in javascript
- first class functions: everything you can do with other types, you can do with functions
- function name can be anonymous
- function body is the "CODE" property of function object

### 3.7 Expression and function expression
a unit of code that results in a value
ex: a=3;
function expression
ex: var anonymousFunc = function(){;}

### 3.8 Statement and function statement
a unit of code that does not return in a value
ex: if (){;}
function statement:
function funname(){;}

### 3.9 By Value and By Reference in Javascript
- By value: a = 2; b=a; //a有個位址存2，b有另外一個位址存2
- By reference: var c={a＝"test"}; d = c;//對物件而言，c和d都"指向"同一個位址
因此，對純值而言，是by value，對物件(object)是by reference

### 3.10 Object, function, and this
當創造function，並呼叫它，this會指向global context的window object
但是當在物件X裡面創造function時，function裡的this會指向物件X，另一方面，若在X裡的function在創造一個function時，該function的this反而會指向global variable，而並非指向X，解決方式就是在設定一個變數把this的address指定給該變數
```javascript
//改變前
var X = {
    name: 'object X',
    log_function: function(){
        this.name = 'change object x';
        var func2 = function(newname){
            this.name = newname; //這邊會指向global variable
        }
        func2('change object x again');
        console.log(this.name);//還是change object x
    }
};
//改變後
var X = {
    name: 'object X',
    log_function: function(){
        var self = this;//把this所指的位址指定給self變數
        self.name = 'change object x';
        var func2 = function(newname){
            self.name = newname; //這邊會指向object X
        }
        func2('change object x again');
        console.log(this.name);//變成change object x again
    }
};
```

### 3.11 Array in Javascript
Array是任何東西的集合，使用[]來包含其中的元素。
由於javascript是dynamic type，所以Array裡的元素可以是不同型別。

### 3.12 arguments and spread in javascript
- arguments: all parameters you pass to a function, which is a keyword could list all the parameters，簡單來說就是傳進函數的參數陣列

### 3.13 function overloading in javascript
not support

## 4. 語言的風格與特性
### 4.1 危險的壞習慣
- Javascript其實可以不需要分號，syntax parser遇到enter(return)的字元會自動加入分號，也因為這個特性，程式設計師需要自己加分號來避免一些語意判斷上的錯誤。
- 如果選擇不用分號的話，其中三種情況必須加入分號
    - (: 在括號前加分號
    - [: 在中括號前加分號
    - \`: 在模板字符(反引號)前加分號 

### 4.2 Immediately invoked function expressions(IIFEs)
- Function expression
```javascript
    //function expression
    var greetFunc = function(name){
        console.log('Hello '+name);
    }
```
- Function statement
```javascript
    //function statement
    function greet(name){
        console.log('Hello '+name);
    }
```
- IIFEs:創造函數之後，立刻呼叫它，使用()
```javascript
//格式1
var greeting = function(name){
    return 'Hello '+name
}('John');
//格式2
(function(name){
        console.log('Hello '+ name)
    }('John')
);
```
- IIFEs and Safe code
當code被包在IIFEs其中的變數不會跟其他變數衝突 

### 4.3 Closure in javascript
當某個function的execution context結束之後，會留下其中的變數在記憶體中，而繼續執行其中的匿名函數時，就會去參照其中的變數值，這個範圍稱為該函數的closure(閉包)
Closure example1:
```javascript
function greet(whattosay){
    return function(name){
        console.log(whattosay + ' '+ name );
    }
}
var sayHi= greet('Hi ');
sayHi('Tony');// Hi Tony
```
Closure example2:
```javascript
function buildFunctions(){
    var arr = [];
    for (var i = 0 ; i < 3 ; i++){
        
        arr.push(
            function(){
                
                console.log(i);
                
            }
        );
    }
    return arr;
}
var fs = buildFunctions();
fs[0]();
fs[1]();
fs[2]();
```
### 4.4 Closures and Callback
callback function: a function you give another function, to be run when the other function is finished

### 4.5 call, apply and bind in javascript
Function is a special type of object.

All functions defaultly contain call, apply, and bind function(method)
- bind: 傳一個oject X進入另一個function object的context，function裡的this會指向X
- call: 傳入一個object X進入另一個function object的context並執行它，function裡的this會指向X
- apply: 傳入一個object X進入另一個function object的context並執行它，function裡的this會指向X，但是和call不同，它傳入的參數必須是個array
- function borrowing: 借用函數的功能
- function currying: 複製函數並預先設定參數
```javascript
var person = {
    firstname: 'John',
    lastname: 'Doe',
    getFullName: function() {
        
        var fullname = this.firstname + ' ' + this.lastname;
        return fullname;
        
    }
}

var logName = function(lang1, lang2) {

    console.log('Logged: ' + this.getFullName());
    console.log('Arguments: ' + lang1 + ' ' + lang2);
    console.log('-----------');
    
}

var logPersonName = logName.bind(person);
logPersonName('en');

logName.call(person, 'en', 'es');
logName.apply(person, ['en', 'es']);

(function(lang1, lang2) {

    console.log('Logged: ' + this.getFullName());
    console.log('Arguments: ' + lang1 + ' ' + lang2);
    console.log('-----------');
    
}).apply(person, ['es', 'en']);

// function borrowing
var person2 = {
    firstname: 'Jane',
    lastname: 'Doe'
}

console.log(person.getFullName.apply(person2));

// function currying
function multiply(a, b) {
    return a*b;   
}

var multipleByTwo = multiply.bind(this, 2);
console.log(multipleByTwo(4));

var multipleByThree = multiply.bind(this, 3);
console.log(multipleByThree(4));
```

### 4.6 Function Programming in Javasscript
- 可以在function參數定義function參數，而在呼叫的時候才去定義他，這可以讓同一個函數做不同的事情
- 實例:[underscore.js](http://underscorejs.org)

### 4.7 Classical Inheritance and prototype Inheritance
#### 4.7.1 繼承(Inheritance)
物件可以取用另一個物件的屬性以及方法
#### 4.7.2 古典繼承
such as Java
#### 4.7.3 原型繼承
Such as Javascript
每個javascript object都有一個proto object，而每個proto object又會有一個proto object

這種連結就是prototype chain

### 4.8 Function Reflection and Extend
- Reflection: an object can look at itself, listing and changing its properties and methods 

> 使用for (var X in OBJECT)的語法來知道OJECT中的properties和methods

而extend就是基於這個概念發展出來，用來組合object

### 4.9 Function constructor
用來創造object的function，函數字首大寫
使用new關鍵字
```javascript
fucntion Pserson(){
    this.firstname = 'John';
    this.lastname = 'Doe';
}
var john = new Person();
console.log(john);
```
new回先創一個空的object，並且會去invoke Person(),而留下來的變數(firsname, lastname)就成為john的properties
- 一些內建的函數建構子(String(), Number())創造出來的是物件而不是純值

### 4.10 Array and for-in
Array其實是一個object
但也是一個function constructor，用for in會把開發者定義的方法也列出來，因此還是用
for (var i;....)

### 4.11 Object.create(object)
這個方法可以創建物件的prototype

### 4.12 ES6 and Classes
Javascript裡面的class就是一個object，而不是一個template，其中的格式和Java非常像。

### 4.13 var, const, and let
- var: 一般變數的宣告
- const: 常數的宣告，只會在function/if/for的 {} 內作用
- let: 只會在function/if/for的 {} 內作用的變數，如下
```javascript
function test(){
    let name = 'john';
    if (true){
        let name = 'bill';
    }
    console.log(name);//will be 'john'
}
```
### 4.14 型別小工具
- typeof : 回傳變數的型別
- instanceof: X instanceof Y，若是true則表示X是Y的instance

### 4.15 嚴謹模式(Strict Mode)
使用方式：
```javascript
'use strict';
var person;
persom = {}; //will cause error in strict mode
```
## 5. Other Side of Javascript
### 5.1 Open source education
- 不要害怕打開開元程式碼
- [Git hub](https://github.com)
- 能不能讀懂原始碼
- 能不能了解它的結構/框架，並從中獲得靈感

### 5.2 Check jQuery
1. jQuery會先設定與確認執行環境
2. jQuery實際上是一個array，它的prototype有許多操作Array的方法

### 5.3 Code Commenting
好的註解有助於了解，因為JS太過簡潔了

### 5.4 typescript, ES6, Transpile languages
Transpile language: 用來轉成另外一種程式語言的程式語言
像是typescript就會被轉成javascript
###### tags: `javascript`
