JS中定義對象的幾種方式
- 字面量及基於已有對象擴充其屬性和方法
- 工廠模式
- 構造函數的方式
- 基於原型(prototype)的方式
- 動態原型的方式
- ES6的Class
一,字面量及基於已有對象擴充其屬性和方法

let obj = {} obj.name = 'Jett' obj.sayHello = function () { console.log('Hello, ', this.name) }
弊端: 可復用性不強(只適用於臨時生成的一個對象),如果需要使用多個對象,還需要重新擴展其屬性和方法
二,工廠模式

function createObject(username, password) { let object = new Object(); object.username = username; object.password = password; object.get = function () { alert(this.username + ", " + this.password); } return object; }
工廠模式的實質還是基於已有對象擴充其屬性和方法,只不過把創造對象的方法封裝了,當需要創建多個對象的時候不需要重復寫代碼。
不過上面的有個缺陷就是每次創建對象的時候,對象的對應的方法都會被創建一次,即方法不能被創建的所有對象共享。
優化:

let get = function () { alert(this.username + ", " + this.password); } function createObject(username, password) { let object = new Object(); object.username = username; object.password = password; object.get = get return object; }
擴展:JS實現單例模式

let Singleton = function( name ){ this.name = name; }; Singleton.prototype.getName = function(){ alert(this.name); }; Singleton.getInstance = (function(){ let instance = null; return function (name) { if (!instance) { instance = new Singleton(name); } return instance; } })();
三,構造函數方式

function Person (username, password) { //在執行第一行代碼前,js引擎會為我們生成一個對象 this.username = username; this.password = password; this.getInfo = function () { alert(this.username + ", " + this.password); } //此處有一個隱藏的return語句,用於將之前生成的對象返回 //只有在后面用new來調用構造函數的情況下,才會出現注釋所述的這兩點情況 }
該方法的弊端也是跟工廠模式類似,對於一些公有的方法需要重復聲明
四,基於原型prototype
對象會從其原型上繼承屬性和方法,所以我們可以把公有的屬性放在原型上,把私有的屬性放在構造函數內部
原型+構造函數

//使用原型+構造函數方式來定義對象 function Person (username, password) { //在執行第一行代碼前,js引擎會為我們生成一個對象 this.username = username; this.password = password; //此處有一個隱藏的return語句,用於將之前生成的對象返回 //只有在后面用new來調用構造函數的情況下,才會出現注釋所述的這兩點情況 } // 在構造函數的原型屬性上添加公有方法/屬性 Person.prototype.getInfo = function() { alert(this.username + ", " + this.password); }
五,動態原型的方式
在構造函數內部通過標志量讓所有對象共享一個方法

//使用原型+構造函數方式來定義對象 function Person (username, password) { //在執行第一行代碼前,js引擎會為我們生成一個對象 this.username = username; this.password = password; //此處有一個隱藏的return語句,用於將之前生成的對象返回 //只有在后面用new來調用構造函數的情況下,才會出現注釋所述的這兩點情況 if (Person.flag === undefined) { // 在構造函數的原型屬性上添加公有方法/屬性 Person.prototype.getInfo = function() { alert(this.username + ", " + this.password); } Person.flag = true } }
沒多大意義,跟四區別不大
六,ES6 的Class
在Class的構造函數中的屬性為私有屬性,Class內聲明的方法為公有屬性

class Person { constructor (username, password) { // 定義私有屬性 this.username = username; this.password = password; } // 公有方法 getInfo = function() { alert(this.username + ", " + this.password); } }