javascript之面向對象總結

JavaScript之面向對象總結

前言:在ECMAScript中是沒有類的概念的,因此它的對象與基於類的語言中的對象不一樣。ECMA-262把對象總結爲:「無序屬性的集合,其屬性包含基本值、對象或者函數」。

1、理解對象

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

  1. [[Configurable]]:表示可否經過delete刪除屬性從而從新定義屬性,默認爲true
  2. [[Enumerable]]:表示可否經過for-in循環返回屬性,默認爲true
  3. [[Writeable]]:表示可否修改屬性,默認爲true
  4. [[Value]]:包含這個屬性的數據值,默認值爲undefined
ps:要修改默認的特性,必須使用 Object.defineProperty

訪問器屬性:包含一對兒gettersetter函數,不包含數據值

訪問器屬性也有4個特性:prototype

  1. [[Configurable]]:表示可否經過delete刪除屬性從而從新定義屬性,默認爲true
  2. [[Enumerable]]:表示可否經過for-in循環返回屬性,默認爲true
  3. [[Get]]:讀取屬性時調用的函數,默認值爲undefined
  4. [[Set]]:寫入屬性時調用的函數,默認值爲undefined
訪問器屬性不能直接定義,必須經過 Object.defineProperty來定義

讀取屬性的特性,經過Object.getOwnPropertyDescriptor方法

2、建立對象

一、經過字面量或者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("巴菲特")
相關文章
相關標籤/搜索