JavaScript - 入門

自我介紹

{
    "name": "洪名辰",
    "gender": "男",
    "position": "前端工程師",
    "skill": {
        "Front-End":{
            "basic": ["HTML", "CSS", "Javascript", "SEO"],
            "JS-framework": ["AngularJS", "ReactJS"],
            "CSS-extend": ["Sass", "Susy"],
            "tools":["Sublime", "Gulp"]
        },
        "Back-End":{
            "basic": ["C#", "Javascript"],
            "framework": ["Asp.Net MVC", "NodeJS"],
            "tools":["Visual Studio", "Sublime"]
        }
    }
}

Agenda

  1. 簡介

  2. 變數與型別

  3. 基礎物件概念

  4. 物件導向

JavaScript 簡介

「JavaScript 是這個世界上被誤解最深的程式語言」

Douglas Crockford

JavaScript != Java

JavaScript 是物件導向程式語言

物件導向

ECMAScript是什麼?

  • 一套標準

  • JavaScript 規格書

JavaScript 變數與型別

所有東西都是物件(object)

- 除了這五個原始型別(Primitive Type)

  • 數值 (number)

  • 字串 (string)

  • 布林 (boolean)

  • null

  • undefined

物件都具有容器的特性(Container)

var car = {};

car.name = 'BMW';

console.log(car.name); //BMW
console.log(car['name']); //BMW

var demo = function(){
    return "Hello World";
}

demo.qqqq = 'qqqq';

console.log(demo.qqqq); //qqqq

var a = "aaa";

a.name = "a"; // 沒有效果

console.log(a.name); // undefined

JavaScript 是動態型別語言

var car = {};

typeof(car); //object

car = "car";

typeof(car); //string

car = 1;

typeof(car); //number

Javascript 型別系統

圖片來源:http://goo.gl/2dsj4f

儘量使用物件實字 (literal notation)

var car;

car = {}; //literal notation

car.name = "BMW";

/**
*
* anti-pattern
*
**/

var car2;

car2 = new Object();

car2.name = new String("BMW");

原始型別

原始型別:數值(number)

var a = 10;

/*
* 應避免使用
*/
var a = new Number(10);

var a = Number('10'); //10,轉型
var a = Number('10aa'); //轉型失敗 --->NaN
var a = +"10"; //10

/*
* 常見的使用技巧
* 避免出現NaN,請使用parseInt、parseFloat。
* 務必指定基數
*/
var a = parseInt('10aa', 10); //10,字串解析

使用方式

Number 內建屬性及方法說明:https://goo.gl/3GfWl8

原始型別:字串(string)

var a = 'Jerry';

/*
* 應避免使用
*/
var a = new String('Jerry'); // String {0: 'J', 1: 'e', 2: 'r', 3: 'r', 4: 'y' }
var a = String('Jerry');


/*
* 常見的使用技巧
*/
var b = a.length; // 5,length可取得字串長度
var c = a[0]; // "J",取得第一個字元 

使用方式

String 內建屬性及方法說明:https://goo.gl/xErvit

原始型別:布林(boolean)

var a = true;

/*
* 應避免使用
*/
var a = new Boolean(false);
var a = Boolean('false');
var a = Boolean('0');
var a = Boolean(0);

使用方式

Boolean 內建屬性及方法說明:https://goo.gl/CEmIH6

布林型別常用技巧

  • 隱含比對 (自動轉型)

    • == 或 !=

  • 明確比對

    • === 或 !==

Truthy跟Falsy值

  • False, 0, ""

  • null, undefined (null及undefined只有互相比較為true)

  • NaN (不管跟誰比都是false)

註:物件比較時,以參考記憶體位置作比較

Falsy值得常用技巧

function(str, num){
    var str = str || 'Jerry';
    var num = num || 100;
}

物件型別

物件型別

  • 原生物件

    • 於ECMAScript 標準定義的物件型別
      • 使用者自定義物件型別
        • var car = {};
      • 內建物件型別
        • Array, Date, Math, RegExp
        • Number, String, Boolean, Object
  • 宿主物件

    • 由 JavaScript 執行環境提供的物件
      • window 物件 (Browser)
      • global 物件 (Node.js) 

原生物件:陣列(Array)

var a = [];

/*
*  應避免使用
*/
var a = new Array();

/*
*  常用技巧
*/
a[0] = "Jerry";
a[1] = "Anna";
a.push("Ray");
a.indexOf("Jerry"); //0
a.splice(0,1);

使用方式

Array 內建屬性及方法說明:https://goo.gl/aeeZI

原生物件:日期(Date)

var a = new Date();
var a = new Date(10000);
var a = new Date('2015-02-21');

使用方式

Date 內建屬性及方法說明:https://goo.gl/DaGfQ

JavaScript 基礎物件概念

所有物件資料都從根物件開始連結 (Chain)

圖片來源:http://goo.gl/4Lyjc

探討JavaScript物件資料結構

//物件
window.document.form[0]; 

//宣告變數a
var a = window.document.form[0]; 

//型別
typeof(a);

//重新賦值
a = '123';

a == window.document.form[0]; //??

探討JavaScript物件資料結構

//宣告物件
window.document.jj = { name:"Jerry"}

//宣告變數a
var a = window.document.jj; 

//型別
typeof(a);

//重新賦值
a.name = '123';

a == window.document.jj; //??

函式物件(function)

  • function 是個特殊物件

  • function 的兩大特色

    • JS 的一級物件 (first-class object)
      • 可以動態被建立
      • 可以指定給變數,也可以複製給其他變數
      • 可以擁有自己的屬性及方法
    • 提供了變數作用域 (scope)
      • 不是以區塊(block){ }建立作用域,有別於其他程式語言

函式的兩種表示法

  • 函式表示式

    •  var a = function (){ }

  • 函式宣告式

    • function a (){ }

全域變數 vs 區域變數

  • 宣告變數

    • 一律透過var 宣告

  • 區域變數

    • 區域變數的範圍是靠function 區隔的
      ( 並非以大括號做區隔 )

  • 全域物件

    • 意即根物件(Root Object) 的屬性/變數

問題

var a = "Jerry"; //全域變數

var b = function(){
    
    console.log(a);
   
    var a = "Ray"; //區域變數
    
    console.log(a);
}
b(); //會印出什麼?

JavaScript Hoisting

var a = "Jerry"; //全域變數

var b = function(){

    var a;

    console.log(a);
    
    a = "Ray"; //區域變數
    
    console.log(a);

}

b(); 
// undefined
// "Lin"

立即函式(immediate Function)

/*
* 第一種寫法,JSHint推薦寫法
*/
(function(a, b){
    var c;
    // ...
}(a, b));

/*
* 第二種寫法,注意右括號 
*/
(function(a, b){
    var c;
    // ...
})(a, b);

使用方式

  • 主要用途
    • 限制變數存在的作用域
    • 讓變數不輕易變成全域變數的方法

回呼模式(Callback Pattern)

var findNodes = function(){
    var i = 1000000,
        nodes = [],
        found;

    while(i){
        i = i-1;
        // 這裡是很複雜的邏輯...
        nodes.push(found);
    }
    return nodes;
}

var hide = function(nodes){
    var i = 0,
        max = nodes.length;
    for(i = 0;i < max; i+=1)
    {
        nodes[i].style.display = "none";
    }
}


//執行
hide(findNodes());

回呼模式(Callback Pattern)

var findNodes = function(callback){
    var i = 1000000,
        nodes = [],
        found;

    while(i){
        i = i-1;
        // 這裡是很複雜的邏輯...
        
        //執行回乎
        if(typeof callback === "function")
        {
            callback(found);
        }

        nodes.push(found);
    }
    return nodes;
}

// 使用匿名函式,就不用定義hide
findNodes(function(node){
    node.style.display = "none";
});

閉包(Closure)

  • 閉包的特性

    • 在特定函式中存取另一個函式的變數

    • 外層函式宣告的變數可以在內層函式中使用

    • 重點觀念:重用域連結 (Scope Chain)

  • 閉包的程式碼外觀

    • 運用在巢狀函式的定義中

閉包(Closure)範例

var a = function(){
        var x = 100;
        return function(){
            x = x - 10;
            return x;
        }
    }

var b = a();

b(); //90
b(); //80

立即函式及閉包的應用

for(var i=0;i<10;i++){
  setTimeout(function(){
    console.log(i);
  }, 0);
  // console.log(i);
}

//使用立即函式 和 閉包特性,來達到
for(var i=0;i<10;i++){
    (function(){
        var j = i;
        setTimeout(function(){
            console.log(j);
        }, 0);
    }());
}

總結

重點回顧

  • 所有東西都是物件,除了五個原始型別

  • 物件具有容器的特性

  • 使用var 宣告變數

  • 儘量使用物件實字,
    只有Date 及自定義物件型別才用到new

  • 隱含比對 & 明確比對

  • Truthy & Falsy

  • 物件比對

重點回顧

  • 宿主物件

  • JavaScript 物件資料結構

  • 作用域 (Scope)是由 function做區隔

  • Hoisting

  • 立即函式 (Immediate Function)

  • 回呼模式 (Callback Pattern)

  • 閉包 (Closure)

沒有講到的部分

- JavaScript 物件繼承

推薦學習書籍

  • JavaScript 大全 (犀牛書)

  • JavaScript 設計模式

  • JavaScript 優良部份

延伸學習

  • React&Flux

  • Angular

  • Node.JS

感謝聆聽!

Javascript 入門

By 洪名辰

Javascript 入門

  • 805