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