PS:今天上午,非常郁悶,有很多簡單基礎的問題搞得我有些迷茫,哎,代碼幾天不寫就忘。目前又不當COO,還是得用心記代碼哦!
後面兩章中提到的實作繼承的方法,都是《Object-Oriented JavaScript》第六章說起的,書中最後也做了總結:
In this chapter you learned quite a few ways (patterns) for implementing inheritance.
The different types can roughly be divided into:
- Patterns that work with constructors
- Patterns that work with objects
You can also classify the patterns based on whether they:
- Use the prototype
- Copy properties
- Do both (copy properties of the prototype)
第六章介紹了一些繼承的方法,分為兩模式:
基于構造函數生成對象的模式
直接繼承對象的模式
也可以按照另一種思路分類:
應用了原型prototype
複制屬性
複制原型的屬性
可以說,這是實作繼承的最核心的内容,實踐中常常交織在一起。回顧下前文介紹的基本繼承方法:
//構造函數 應用原型鍊
Coder.prototype = new Person("無名");
//構造函數 同享原型鍊
Coder.prototype = Person.prototype;
//構造函數 應用原型鍊 隻繼承原型屬性方法
function extend(Child,Parent){
var F = function(){};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
}
//構造函數 應用原型鍊 複制原型屬性
function extend2(Child,Parent){
var p = Parent.prototype;
var c = Child.prototype;
for(var i in p){
c[i] = p[i];
}
}
//繼承對象 複制屬性
function extendCopy(p, c){
var c = c || {};
for(var i in p){
c[i]=p[i];
}
return c;
}
//繼承對象 深複制
function deepCopy(){}
//繼承對象 應用原型鍊
function object(o){
function F(){};
F.prototype = o;
return new F();
}
//繼承對象 應用原型鍊 複制屬性
function objectPlus(o, stuff){}
//繼承對象 複制屬性
function multi(){}
遺留的一些事件
1.之前的文章中出現以下代碼
function Person(name){
this.name = name;
}
Person.prototype.sayHello = function(){
alert(this.name);
};
function Coder(name,language){
this.language = language;
this.name = name;
}
Coder.prototype = new Person("無名");
Coder.prototype.constructor = Coder;
Coder.prototype.code = function(){
alert("i am a "+this.language+" coder");
};
我們改革下這段代碼,主要處理 子類調用父類的構造函數中初始化代碼,自行對比優缺點:
function Person(name){
this.name = name;
}
Person.prototype.sayHello = function(){
alert(this.name);
};
function Coder(name,language){
Person.apply(this,arguments);
this.language = language;
}
extend2(Coder,Person);
Coder.prototype.code = function(){
alert("i am a "+this.language+" coder");
};
每日一道理
試試看——不是像企鵝那樣靜靜的站在海邊,翹首企盼機會的來臨,而是如蒼鷹一般不停的翻飛盤旋,執著的尋求。 試試看——不是面對峰回路轉、雜草叢生的前途枉自嗟歎,而是披荊斬棘,舉步探索。 試試看——不是拘泥于命運的禁锢,聽憑命運的擺布,而是奮力敲擊其神秘的門扉,使之洞開一個新的天地。微笑着,去唱生活的歌謠。
通過 Person.apply(this,arguments)調用父類的構造方法,extend2繼承父類的原型方法,最後再擴充原型方法。
如果擴充的原型方法很多,我想你一定有辦法知道如果通過之前的基礎方法,寫出一個新的符合你自己要求的繼承機制。
我們完全可以寫一個 extend3(Coder,Person,stuff)的方法~如果你有須要這麼做的話。
2.幾個函數操作
obj instanceof F // 判斷對象obj是否是F的執行個體
F.prototype.isPrototypeOf(obj)//作用同上
obj.constructor // 傳回obj的構造函數
obj.hasOwnProperty('屬性名') // 判斷obj是否有屬于自己的屬性,而不是他所指原型的屬性
這幾個操作幫助懂得原型鍊、繼承過程,在實踐中也有很重要的作用。
3.關于 子“類”調用父"類"的方法、屬性
有三個類 Shape TwoDShape Triangle 形狀、2D形狀、三角形,他們繼承關系。
對象執行個體須要實作一種方法:toString() 不僅要輸出自己的類名,還要輸出祖輩的類名。
如何實作呢?
由于繼承的實作方法挺多的,而且子“類”的這種需求變幻無窮,如何有效控制,文章(本人能力無限)一句話說不清楚,《o-o》中也隻是交叉地說了一下。
基本的一種思路是 在 Parent加一個靜态屬性uber指向Child.prototype
function extend(Child,Parent){
var F = function(){};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
Child.uber = Parent.prototype;
}
function Shape(){};
Shape.ptototype.name = "shape";
Shape.prototype.toString = function(){
var result = [];
if(this.constructor.uber){
result[result.length] = this.constructor.uber.toString();
}
result[result.length] = this.name;
return result.join(', ');
};
function TwoDShape(){};
extend(TwoDShape,Shape);
TwoDshape.prototype.name = "2dShape";
function Triangle(side, height){
this.side = side;
this.height = height;
};
extend(Triangle, TwoDShape);
Triangle.prototype.name = "triangle";
Triangle.prototype.getArea = function(){return this.side*this.height/2;};
var my = new Triangle(3,4);
my.toString();
複制原型屬性的時候
function extend2(Child,Parent){
var p = Parent.prototype;
var c = Child.prototype;
for(var i in p){
c[i] = p[i];
}
c.uber = p;
}
對象直接繼承的時候
function object(o){
var n;
function F(){}
F.prototype = o;
n = new F();
n.uber = o;
return n;
}
下面的實作 都是 《o-o》第六章中說起的
執行個體、原型、構造函數 誰可以最直接地調用方法uber ,以及要發生什麼效果,按需實作。
uber 是源于德語,super是js中的一個關鍵詞,是以建議應用uber
到此,《o-o》第六章的内容都介紹完畢,内容基于自己的梳理,增加了自己的懂得,難免有疏漏的地方,請教正。
歡迎大家看原著,國内也出了翻譯版~
文章結束給大家分享下程式員的一些笑話語錄: 蘋果與谷歌之争就是封閉收費與自由免費思想之争。(别急着把google來膜拜哦?那可是一家公司,以賺錢為目标的公司!當年我Party就是這樣把廣大勞動人民吸引過來的。今天的結果你們都看到了。)