Douglas Crockford指出javascript是世界上最被誤解的程式語言。由於javascript缺少常見的物件導向概念,許多程式猿認為javascript不是一個合適的語言。我在做第一個javascript專案時候也發現不能將程式碼放在一個類中。其實大部分程式猿不知道javascript可以物件導向。
瀏覽器大戰時代,Netscape的執行官招來了一個叫Brendan Eich的聰明人,發明了livescript(就是現在的javascript)語言,用來執行在瀏覽器端。它不像c++和java一樣基於類,而是基於原型繼承模型設計的。 OOP非常適合livescript這種動態語言。
由於當時市場影響,這種新的語言需要看起來像java。java在當時非常耀眼流行,Netscape的執行官希望新語言是”java的小兄弟“。這就是為啥新語言叫javascript。
JavaScript and prototype-based OOP
下面是javascript的oop例子,先來搞出一個animal的物件:
var genericAnimal = Object.create(null);
- 1
Object.create(null)
建立空物件。下面往這個新物件上新增新屬性和方法:
genericAnimal.name = 'Animal';
genericAnimal.gender = 'femal';
genericAnmal.description = function () {
return 'Gender: ' + this.gender + '; Name: ' + this.name;
};
- 1
- 2
- 3
- 4
- 5
genericAnimal就是一個物件,可以這樣使用:
console.log(genericAnimal.description());
- 1
我們可以使用genericAnimal作為原型,建立其他物件,就像拷貝物件(cloning the object):
var cat = Object.create(genericAnimal);
- 1
我們建立了cat物件,cat物件是genericAnimal的clone版。將cat物件作為原型,建立其他物件:
var colonel = Object.create(cat);
colonel.name = 'Colonel Meow';
var puff = Object.create(cat);
puff.name = 'Puffy';
- 1
- 2
- 3
- 4
- 5
puff物件可以使用“父物件”繼承來的屬性和方法:
console.log(puff.description());
//Gender: female; Name: Puffy
- 1
- 2
The new keyword and the constructor function
javascript有new關鍵字和建構函式的感念。
function Person(name) {
this.name = name;
this.sayName = function() {
return "Hi, I'm " + this.name;
};
}
var adam = new Person('Adam');
- 1
- 2
- 3
- 4
- 5
- 6
- 7
實現繼承有點複雜, Ninja物件繼承Person物件:
function Ninja(name, weapon) {
Person.call(this, name);
this.weapon = weapon;
}
Ninja.prototype = Object.create(Person.prototype);
Ninja.prototype.constructor = Ninja;
- 1
- 2
- 3
- 4
- 5
- 6
Understanding delegation and the implementation of prototypes
使用Object.create
建立新物件時候,傳入的物件成了新物件的原型。每個物件都有預設的__proto__
屬性來記錄原型。舉例說明:
var genericAnimal = Object.create(null);
// genericAnimal.__proto__ points to null
- 1
- 2
使用genericAnimal作為原型建立一個新的空物件:
var rodent = Object.create(genericAnimal);
rodent.size = 'S';
var capybara = Object.create(rodent);
//capybara.__proto__ points to rodent
//capybara.__proto__.__proto__ points to genericAnimal
//capybara.__proto__.__proto__.__proto__ is null
- 1
- 2
- 3
- 4
- 5
- 6
capybara物件雖然沒有size屬性,但是它可以在原型鏈上查詢size屬性:當呼叫capybara.size
時,首先在capybara物件的本身屬性上查詢,如果沒有找到,則會去capybara.__proto__
所指向的原型上去查詢。如果在capybara.__proto__
也沒有找到,則繼續在capybara.__proto__.__proto__
上查詢。
Creating Object.create
如果有些瀏覽器不支援Object.create
,那麼需要自己實現了:
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function F() {}
F.prototype = o;
return new F();
};
}
http://blog.csdn.net/bdss58/article/details/51284944