今天要稍微跳脫一下下NodeJS,紀錄一下基本的JavaScript物件概念,包含Obeject、Prototype與ES6標準下的Class。
Object(物件)簡要而言就是一系列的名稱/值(name/vaule)組合,亦即多個名稱及其對應的值可以組成一個物件,這邊指的值可以是原始資料、物件或函式,原始資料與物件稱為物件的屬性、函式則作為物件的方法。
JavaScript中的物件紀錄的方式以大括號 { }進行分層。
let person{
firstName: "chw",
lastName: "k",
greet: function(){
// 使用物件內的屬性要以this指向目前物件
console.log("Hello, " + this.firstName + this.lastName);
}
};
物件可以透過函式建構式(function constructor)建置,函式會自動產生新的物件,並透過this
關鍵字變數會指向該物件定義屬性,而建置完成的物件屬性和方法可以用.
或[name]
存取。
實作看看
- 撰寫一個一般函式作為Person物件建構函式,Person物件具有屬性
firstName
、lastName
與方法greet
,greet
的內容包含印出firstName
和lastName
。// 物件建構函式 function Person(firstName, lastName){ this.firstName = firstName; this.lastName = lastName; this.greet = function(){ console.log("Hello, " + this.firstName + this.lastName); }; }
- 建立一個名為chwk的Person物件,並呼叫該物件的
greet
方法。// 建立新物件 let chwk = new Person("chw", "k"); // 呼叫greet() chwk.greet();
- 執行除錯,印出指定句子。
每個物件都具備prototype(原型)的屬性,用於指向另一個物件,透過prototype可以存取另一個物件內部的屬性,又稱為原型繼承(prototypal inheritance)。而物件原型所指向的物件也具有prototype屬性指向其他物件,這樣一連串的關聯產生了prototype chain(原型鏈),在原型鏈中,具有原型繼承的物件可以取得其繼承的prototype指向物件及prototype所繼承的其他prototype指向物件的屬性,使用物件建構函式建置的所有物件都會具有相同的原型繼承。
實做看看
- 撰寫一個一般函式作為Person物件建構函式,Person物件具有屬性
firstName
、lastName
。// 物件建構函式 function Person(firstName, lastName){ this.firstName = firstName; this.lastName = lastName; }
- 在Person物件下的prototype中定義一個
greet
方法。// 物件原型中的函式 Person.prototype.greet = function(){ console.log("Hello, " + this.firstName + this.lastName); }
- 建立兩個新的的Person物件,並同時呼叫
greet
。// 建立新物件 let chw = new Person("chw", "k"); let miguel = new Person("miguel", "h"); // 呼叫greet() chw.greet(); miguel.greet();
- 執行除錯,印出指定句子,可以發現兩個物件都繼承了prototype,因此可以呼叫到其中的
greet
。
Class(類別)是ES6標準中提出建立物件的新方法,提供建立物件新的JavaScript語法,但就程式執行的本質而言並沒有差異,因此只能說是syntatic sugar(語法糖),意即達到簡化語法使開發人員更容易使用,在程式語言的功能上並沒有影響的程式語法,這裡直接用實作來看看Class的使用。
實作看看
- 在VSCode中要使用ES6語法時,先在工作目錄下建立一個
jconfig.json
,並在裡面紀錄編譯選項為ES6,可避免VSCode執行編譯時產生多餘的提示訊息。// jconfig.json { "compilerOptions":{ "target":"ES6" } }
- 開啟一個空白檔案,建立一個Person的Class。
"use strict"; // 使JavaScript引擎執行程式碼時,嚴格審視語法規則 class Person{ // class中的建構函式constructor,透過建構參數firstName、lastName建構Person類別 constructor(firstName, lastName){ this.firstName = firstName; this.lastName = lastName; } // class中的方法撰寫方式 greet(){ console.log("Hello, " + this.firstNmae + this.lastName); } }
- class建構完成後,同樣以
new
建立新的Person,並呼叫greet
方法。// 建立新class let chwk = new Person("chw", "k"); // 呼叫greet() chwk.greet();
- 執行除錯,印出指定句子,成果和透過物件語法執行的成果是相同的。
不知不覺變成一篇長文,雖然ES6所提出的class只是讓開發人員感覺良好的syntatic sugar,身為一個c#愛用者還是免不了覺得愉快,只是要提醒一下,JavaScript中的class只是物件,和c#中的class是完全不一樣的概念,要小心。
https://zh.wikipedia.org/wiki/语法糖
Learn and Understand NodeJS [課程]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto