Skip to content

Instantly share code, notes, and snippets.

@ywwwtseng
Last active January 27, 2019 04:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ywwwtseng/20fb577b4aa68123885220f8e4565890 to your computer and use it in GitHub Desktop.
Save ywwwtseng/20fb577b4aa68123885220f8e4565890 to your computer and use it in GitHub Desktop.
oojs

OOJS

在 Javascript 中, 除了 Primitive value (number, string, boolean, null, undefined) 以外, 從字串 (String) 與陣列 (Array) 等核心功能, 到以 Javascript 建置的瀏覽器 API, 都可以算是物件 (Object).

物件 Object

物件 (Object) 是一批 "數據" 及 "功能" 的集合, 一般我們稱做 "屬性" (properties) 和方法 (methods).

物件可以裝載相關資料與程式碼, 當你要用物件塑造某個 thing, 我們會在這個物件設置屬性來定義這個 thing 的資訊, 設置方法實現這個 thing 的行為.

var person = {
  name: 'William',
  greeting: function() {
    alert('Hi! I\'m ' + this.name + '.');
  },
};

使用 Constructor 函式建立物件實例 (Object instance)

// constructor function
function Person(name) {
  this.name = name;
}

var person = new Person('William');

原型架構的程式語言?

常有人說 Javascript 是原型架構的程式語言, 一個物件都具備一組原型物件作為範本物件, 用來繼承其屬性與方法. 物件的原型物件也可能包含原型物件, 這就是我們所謂的原型鍊 (Prototype chain)

講到繼承,JavaScript 就只有一個建構子:物件。每個物件都有一個連著其他原型(prototype)的私有屬性(private property)物件。原型物件也有著自己的原型,於是原型物件就這樣鏈結,直到撞見 null 為止:null 在定義裡沒有原型、也是原型鏈(prototype chain)的最後一個鏈結。

簡而言之,就是一個物件可以提取並取用另一個物件的 Property 跟 Method.

一個物件除了我們給予的屬性值以外還包含原型 Prototype。當 > Object 查找不到 Property 或 Method,它會沿著 Prototype chain 去查找 Property 或 Method。

原型鏈上的屬性的查詢時間,可能會對效能有負面影響,對程式碼也因而產生明顯問題。另外,試圖尋找不存在的屬性,就一定會遍歷整個原型鏈。 接著,在迭代物件屬性時,每個原型鏈的枚舉屬性都會抓出來。

要檢查物件本身有沒有指定的屬性、也不需要查找整個原型鏈時,你必須使用由 Object.prototype 繼承的 hasOwnProperty 方法。

Prototype

原型 (Prototype) 是 Javascript 物件用以互相繼承功能的機制, 與典型的 OO 程式語言中的繼承方式有所不同.

使用 Prototype 繼承

function Person(name) {
  this.name = name;
}

Person.prototype = {
  greeting: function() {
    alert('Hi! I\'m ' + this.name + '.');
  },
}

function Engineer(name) {
  Person.call(this, name);
}
Engineer.prototype = Object.create(Person.prototype);
Engineer.prototype.coding = function() {
  alert('I am typing the keyboard.');
}

Engineer.prototype.constructor = Engineer;

const engineer = new Engineer('William');

使用 Object.create 繼承

語法

Object.create(proto[, propertiesObject])

範例

var Person = {
  name: 'Default',
  greeting: function() {
    alert('Hi! I\'m ' + this.name + '.');
  },
};


var person = Object.create(Person);
person.name = 'Arron';

類別 Classes

傳統的 OOP 都是先定義類別, 當使用類別建立物件實例後, 根據類別上所定義的所有屬性與函式複製到此實例. 但 Javascript 不會複製這些屬性與函式, 使用原型鍊去連接這些屬性與函式.

ES6 推出了 Classes 讓我們在建立物件實例及繼承時, 用法上與傳統 OOP 語言類似.

class Person {
  constructor(name) {
    this.name = name;
  }
  
  greeting() {
    alert('Hi! I\'m ' + this.name + '.');
  }
}

class Engineer extends Person {
  constructor(name) {
    super(name);
  }
  
  coding() {
    alert('I am typing the keyboard.');
  }
}

在 JavaScript 中使用繼承的時機?

在自己的程式碼裡,特別是剛接觸或小型專案時,你用繼承的頻率可能沒那麼高。若沒真正需要,只是「為使用而使用」繼承,老實說只是浪費時間。但隨著程式碼規模越來越大,你就會找到使用的時間。如果你發現自己開始建立類似功能的多個物件時,就可先建立通用的物件類型,來概括所有共用的功能,並在特定物件類型中繼承這些功能,既方便又有效率。

參考

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment