對於傳統的繼承方式,會存在一定的缺點,分析extjs底層的實現可以解決產生的問題
<script type="text/javascript">
//這裏使用之前說過得混合繼承的方式
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype = {
id: 10,
sayName: function() {
alert(this.name);
}
};
function Boy(name, age, sex) {
//call綁定父類的模板函數(只複製了父類的模板)
Person.call(this, name, age);
this.sex = sex;
}
//原型繼承的方式,既繼承了父類的模板(只是相當於沒有傳入相應的參數),又繼承了父類的原型對象(之前說過的原型對象和模板構造函數都會產生關聯)
Boy.prototype = new Person();
var boy = new Boy('z3', 18, '男');
boy.sayName();
alert(boy.id);
</script>
這裏存在一個缺點,父類的模板函數被調用了兩次,如果對象非常多的話,毫無疑問會造成性能的損耗,因此可以進行以下改進。
<script type="text/javascript">
//這裏使用之前說過得混合繼承的方式
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype = {
constructor: Person, //①
sayName: function() {
alert(this.name);
}
};
function Boy(name, age, sex) {
//call綁定父類的模板函數(只複製了父類的模板)
Boy.superClass.constructor.call(this, name, age); //② 在子類中不再出現父類的信息,做到一定的解耦
this.sex = sex;
}
//自定義extend方法僅僅讓原型繼承一次
// Boy.prototype = new Person();
extend(Boy, Person);
function extend(sub, sup) {
//讓子類只繼承1次父類的原型對象
var F = new Function();
//通過一個臨時變量只接受父類的原型對象
F.prototype = sup.prototype;
//正常的繼承
sub.prototype = new F();
//此時需要還原sub的構造函數
sub.prototype.constructor = sub;
//保存一下父類的原型對象,一方面方便解耦,另一方面方便活得父類的原型對象 見②處代碼
sub.superClass = sup.prototype;
//爲了確保父類的構造函數被處理過,可以加上一個保險 見①出的代碼
if (sup.prototype.constructor == Object.prototype.constructor) {
//手動歡迎父類原型對象的構造器
sup.prototype.constructor = sup;
}
}
var boy = new Boy('z3', 18, '男');
alert(Boy.superClass.constructor); //如果忽略①出的構造函數處理,結果會出現錯誤
boy.sayName(); //z3
</script>