var person = new Object(); person.name = "張三"; person.age = 15; person.say = function(){ alert('hello'); }
上面經過Object構造函數建立了一個對象,併爲它添加了三個屬性。es6
ECMA對象的屬性有兩種:數據屬性和訪問器屬性。函數
var person = { name: "聶赫留朵夫", // 數據屬性 age: 25 } Object.defineProperty(person, "year", { // 訪問器屬性 get: function(){ return 1922; }, set: function(value){ this.age = 25 + value; } })
數據屬性有4個描述其行爲的特性:this
delete
刪除屬性從而從新定義屬性,默認爲true
for-in
循環返回屬性,默認爲true
true
undefined
ps:要修改默認的特性,必須使用
Object.defineProperty
getter
和setter
函數,不包含數據值訪問器屬性也有4個特性:prototype
delete
刪除屬性從而從新定義屬性,默認爲true
for-in
循環返回屬性,默認爲true
undefined
undefined
訪問器屬性不能直接定義,必須經過
Object.defineProperty
來定義
Object.getOwnPropertyDescriptor
方法一、經過字面量或者Object構造函數code
var person = { name: "尤瓦爾•赫拉利" } var car = new Object(); car.name = "法拉利"
優勢:不清楚
缺點:使用同一個接口,會產生大量的代碼對象
二、工廠模式接口
function createPerson(name, age){ var o = new Object(); o.name = name; o.age = age; return o; } var p1 = createPerson("方鴻漸", 14); var p2 = createPerson("墨帶", 20);
優勢:解決了建立多個類似對象的問題
缺點:很明顯,你不知道建立的對象的類型是什麼ip
三、構造函數模式get
function Person(name, age){ this.name = name; this.age = age; } var person = new Person("智人", 25);
建立實例,必需要經過new
關鍵字,new
調用經歷的步驟:原型
this
指向新的對象優勢:能夠將每一個實例都標識爲一種特定的類型
缺點:每一個方法都要在實例上從新建立一遍
四、原型模式
function Person(){} Person.prototype.name = "凱撒大帝"; Person.prototype.age = 500; var p1 = new Person(); console.log(p1.name); // 凱撒大帝 var p2 = new Person();
特色:全部的屬性都是被不少實例共享的,但這個也是一個缺點。這個共享對於函數來講挺好,對於基本類型來講也還能夠(實例上添加的同名屬性能夠覆蓋原型上的),可是對於引用類型來講就是比較突出的問題了(修改一個,其他的也會被修改)。另外,這個模式省略了爲構造函數傳參的方便。
五、構造函數模式和原型模式組合使用
function Person(name, age){ this.name = name; this.age = age; } Person.prototype.getName = function(){ alert(this.name); } var p = new Person("貝多芬", 200);
這種是比較通用的一種方式,結合了構造函數模式和原型模式的優勢,可是這種方式可能對於寫OO語言的人來講,有點兒不友好,畢竟這種寫法有點兒獨特。
六、動態原型模式
function Person(name, age){ this.name = name; this.age = age; if (typeOf this.sayName !== "function") { Person.prototype.sayName = function(){ alert(this.name); } } }
這種模式的好處是把全部的屬性所有都封裝到一個函數裏面,可是會對函數作一個檢測,沒有的狀況下才會去建立
七、寄生構造函數模式
function Person(name, age){ var o = new Object(); o.name = name; o.age = age; o.printName = function(){ console.log(this.name); } return o; } var p = new Person("貝多芬", 55);
這個模式的一個適用場景是改寫原生的對象
八、使用es6
class Person { constructor(name){ this.name = name; } printName(){ console.log(this.name); } } const p = new Person("巴菲特")