OOP

javascript OOP概念是以Prototype為核心實作(Prototype-based programming)

下面是一個不用prototype的方式建立object的方式:

function toString() {
    return '[' + this.name + ',' + this.age + ']';
}

function Person(name, age) {
    this.name = name;
    this.age = age;
    this.toString = toString;
}

p = new Persion();
p.toString();

但這樣global就會多一個不必要的function, 另一種是用匿名function

function Person(name, age) {
    this.name = name;
    this.age = age;
    this.toString = function() {
        return '[' + this.name + ',' + this.age + ']';
    }
}

p = new Persion();
p.toString();

不過這樣每次呼叫建構式時,都會建立一次函式實例。

為了解決這些問題,就要靠prototype了

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

Person.prototype.toString = function() {
    return '[' + this.name + ', ' + this.age + ']';
};

var p1 = new Person('Justin', 35);
var p2 = new Person('Momor', 32);

console.log(p1.toString());   // [Justin, 35]
console.log(p2.toString());   // [Momor, 32]

使用 new 關鍵字時,JavaScript 會先建立一個空物件,接著設定物件的原型為函式的 prototype 特性所參考的物件,然後呼叫建構式並將所建立的空物件設為 this。

JavaScript 在尋找特性名稱時,會先在實例上找尋有無特性,以上例而言,p1 上會有 name 與 age 特性,所以可以直接取得對應的值。如果物件上沒有該特性,會到物件的原型上去尋找,以上例而言,p1 上沒有 toString 特性,所以會到 p1 的原型上尋找,而 p1 的原型物件此時也就是 Person.prototype 參考的物件,這個物件上有 toString 特性,所以可以 找到 toString 所參考的函式並執行。

上面的例子在javascript的實作概念就像是

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

Person.prototype.toString = function() {
    return '[' + this.name + ', ' + this.age + ']';
};

var p = {};
p.__proto__ = Person.prototype;
Person.call(p, 'Justin', 35);

console.log(p.toString());         // [Justin,35]
console.log(p instanceof Person);  // true

以前都會把下面的例子搞混

Person.toString1 = function() {}
Person.prototype.toString2 = function() {}

p = new Person()
p.toString1() // error!
Person.toString1() // ok
p.toString2() // ok

直接把放在class底下,就像是C++ static class function屬於class level,但跟c++不一樣的是object是無法access這個function

Reference

results matching ""

    No results matching ""