《JavaScript高级程序设计》学习笔记(继承)
来源:互联网 发布:网上虚拟充值淘宝原理 编辑:程序博客网 时间:2024/05/29 11:07
《JavaScript高级程序设计》学习笔记(继承)
继承
要用ECMAScript实现继承机制,首先从基类入手。
所有开发者定义的类都可作为基类。出于安全原因,本地类和宿主类不能作为基类。
选定基类后,就可以创建它的子类了。是否使用基类完全由你决定。
抽象类:只用于给子类提供通用函数的不能直接使用的基类。
创建的子类将继承超类的所有属性和方法,包括构造函数及方法的实现。
注意:所有属性和方法都是公用的,因此子类可直接访问这些方法。
子类还可添加超类中没有的新属性和方法,也可以覆盖超类中的属性和方法。
继承的方式
ECMAScript中有多种继承方式,因为JavaScript中的继承机制并不是明确规定的,
而是通过模仿实现的。这意味着所有的继承细节并非由解释程序处理。作为开发者,你有权决定最适用的继承方式。
1. 对象冒充
原理:构造函数使用this关键字给所有属性和方法赋值(即采用类声明的构造函数方式)。
因为构造函数只是一个函数,所以可使ClassA的构造函数成为ClassB的方法,然后调用它。
例如:
function ClassA(col){
this.color = col;
this.show = function(){alert(this.color);};
}
function ClassB(col,n){
this.newMethod = ClassA;
this.newMethod(col);
delete this.newMethod;
this.n = n;
this.show2 = function(){alert(this.n);};
}
var obja = new ClassA('red');
var objb = new ClassB('blue',5);
obja.show();//'red'
objb.show();//'blue'
objb.show2();//'5'
所有的新属性和新方法都必须在删除了新方法的代码行后定义。否则,可能会覆盖超类的相关属性和方法。
对象冒充可以支持多重继承,即一个类可以继承多个超类。
例如:
已经有类ClassX和ClassY
function ClassZ(){
this.newMethod = ClassX;
this.newMethod();
delete this.newMethod;
this.newMethod = ClassY;
this.newMethod();
delete this.newMethod;
}
这里存在一个弊端,如果ClassX和ClassY具有同名的属性或方法,ClassY具有高优先级,因为继承的是最后的类。
2. call()方法
call()方法是与经典的对象冒充方法最相似的方法。
它的第一个参数用作this的对象。其他参数都直接传递给函数自身。
例如:
function ClassA(col){
this.color = col;
this.show = function(){alert(this.color);};
}
var obj = new Object;
ClassA.call(obj,"red")
obj.show();
结合对象冒充方法,只需将前三行的赋值、调用和删除代码替换即可
例如:
function ClassA(col){
this.color = col;
this.show = function(){alert(this.color);};
}
function ClassB(col,n){
//this.newMethod = ClassA;
//this.newMethod(col);
//delete this.newMethod;
ClassA.call(this,col)
this.n = n;
this.show2 = function(){alert(this.n);};
}
3. apply()方法
apply()方法有两个参数,用作this的对象和要传递给函数的参数的数组。
例如:
function ClassA(col1,col2){
this.show = function(){alert(col1+' '+col2)};
}
var obj = new Object;
ClassA.apply(obj,new Array("red","blue"));
obj.show();
结合对象冒充方法,只需将前三行的赋值、调用和删除代码替换即可
例如:
function ClassA(col1,col2){
this.show = function(){alert(col1+' '+col2)};
}
function ClassB(col1,col2,n){
//this.newMethod = ClassA;
//this.newMethod(col);
//delete this.newMethod;
ClassA.apply(obj,new Array(col1,col2));
this.n = n;
this.show2 = function(){alert(this.n);};
}
同样的,第一个参数仍是this。第二个参数是只有一个值color的数组。
可以把ClassB的整个arguments对象作为第二个参数传递给apply()方法
例如:
function ClassA(col1,col2){
this.show = function(){alert(col1+' '+col2)};
}
function ClassB(col1,col2,n){
//this.newMethod = ClassA;
//this.newMethod(col);
//delete this.newMethod;
ClassA.apply(obj,arguments);
this.n = n;
this.show2 = function(){alert(this.n);};
}
只有超类中的参数顺序与子类中的参数顺序完全一致时才可以用arguments传递参数对象。
如果不是,就必须创建一个单独的数组,按照正确的顺序放置参数。此外,还可使用call()方法。
4. 原型链
prototype对象的任何属性和方法都被传递给那个类的所有实例。
原型链利用这种功能来实现继承机制。
例如:
function ClassA(){}
ClassA.prototype.color = "red";
ClassA.prototype.show = function(){alert(this.color);};
function ClassB(){}
ClassB.prototype = new ClassA();//把ClassB的prototype属性设置成ClassA的实例
var obj = new ClassB();
obj.show();
注意:调用ClassA的构造函数时,没有给它传递参数。这在原型链中是标准做法。要确保构造函数没有任何参数。
注意:子类的所有属性和方法都必须出现在prototype属性被赋值后,因为prototype属性被替换成新对象后,原始对象将被销毁。
例如:
function ClassA(){}
ClassA.prototype.color = "red";
ClassA.prototype.show = function(){alert(this.color);};
function ClassB(){}
ClassB.prototype = new ClassA();
ClassB.prototype.show2 = function(){alert('2');};
var obj = new ClassB();
obj.show();
obj.show2();
在原型链中,对ClassB的所有实例,instanceof为ClassA和ClassB都返回true。
例如:
alert(obj instanceof ClassA);
alert(obj instanceof ClassB);
在ECMAScript的弱类型世界中,这是极其有用的工具,不过使用对象冒充时不能使用它。
原型链的弊端是不支持多重继承。记住,原型链会用另一类型的对象重写类的prototype属性。
5. 混合方式
用对象冒充继承构造函数的属性,用原型链继承prototype对象的方法。
例如:
function ClassA(col){
this.color = col;
}
ClassA.prototype.show = function(){alert(this.color);};
function ClassB(col){
ClassA.call(this,col)
}
ClassB.prototype = new ClassA();
var obj = new ClassB('red');
obj.show();
alert(obj instanceof ClassA);
alert(obj instanceof ClassB);
用对象冒充继承ClassA类的color属性,用原型链继承ClassA类的方法。
由于这种混合方式使用了原型链,所以instanceof运算符都返回true。
- 《JavaScript高级程序设计》学习笔记(继承)
- JavaScript高级程序设计-学习笔记5(继承)
- javascript高级程序设计学习(四)----------继承
- 《JavaScript高级程序设计》学习笔记(语句)
- 《JavaScript高级程序设计》学习笔记(BOM1)
- 《JavaScript高级程序设计》学习笔记(BOM2)
- 《JavaScript高级程序设计》学习笔记(DOM1)
- 《JavaScript高级程序设计》学习笔记(DOM2)
- 《JavaScript高级程序设计》学习笔记(函数)
- 《JavaScript高级程序设计》学习笔记(DOM2)
- 《JavaScript高级程序设计》学习笔记(拖放)
- JavaScript高级程序设计学习笔记(一)
- JavaScript高级程序设计学习笔记(1)
- javaScript高级程序设计学习笔记(1)
- javaScript高级程序设计学习笔记(2)
- javaScript高级程序设计学习笔记(4)
- Javascript高级程序设计学习笔记(二)
- 《JavaScript高级程序设计》学习笔记(第一章)
- 《JavaScript高级程序设计》学习笔记(DOM2)
- 《JavaScript高级程序设计》学习笔记(原始类型)
- 《JavaScript高级程序设计》学习笔记(函数)
- 将不同类型的ADO数据源导出到Excel(解决方案)
- 原创兔子GIF图图之一
- 《JavaScript高级程序设计》学习笔记(继承)
- log4j指南
- 《JavaScript高级程序设计》学习笔记(表单和数据完整性)
- 解决AJAX从前台传递到后台在LINUX下出现乱码
- Symbian中的动态集合Rarray的使用
- javascript中iframe里面的页面调用父窗口js函数的方法。
- 如何提升文档编写能力
- 创业教父马云的经典语录
- VC编程规范