在该实例中,圆形是椭圆形的子类,椭圆形是圆形的超类(父类);同样,三角形(triangle)、矩形(rectangle)和五边形(pentagon)都是多边形的子类,多边形是它们的超类。
***
// 父类 classa function classa(acolor){ this.color = acolor; this.showcolor = function(){ console.log(this.color); } } // 子类 classb function classb(bcolor,bname){ this.newmethod = classa; // 函数名classa只是指向函数的指针,所以这里是将this.newmethod也指向classa这个函数,所以函数classb就拥有了函数classa的方法和属性 this.newmethod(bcolor); delete this.newmethod; // 该操作使得实例化的对象不需要多次继承同一个函数了,因为继承一次就可以了。注意:新增的属性和方法最好都写在 删除对另一个函数引用的后面,因为如果在前面定义的话,如果父类刚好有该属性或者方法你就会把父类的属性和方法 给覆盖掉。 this.name = bname; this.sayname = function(){ console.log(this.name); } } // -------------------------------------- var obja = new classa("blue"); var objb = new classb("red", "john"); obja.showcolor(); // blue objb.showcolor(); // red objb.sayname(); // john
function classz() { this.newmethod = classx; this.newmethod(); delete this.newmethod; this.newmethod = classy; this.newmethod(); delete this.newmethod; }
这里存在一个弊端,如果存在两个类 classx 和 classy 具有同名的属性或方法,classy 具有高优先级。因为它从后面的类继承。除这点小问题之外,用对象冒充实现多重继承机制轻而易举。
// call方法 function classa(acolor){ this.color = acolor; this.showcolor = function(){ console.log(this.color); } } function classb(bcolor){ classa.call(this,bcolor); // 这里的this指的是classb实例化的对象,让this调用函数classa,达到继承效果。第二个参数是对应classa的参数 } var obja = new classa('blue'); var objb = new classb('red'); obja.showcolor(); // blue objb.showcolor(); // red
function classa(acolor){ this.color = acolor; this.showcolor = function(){ console.log(this.color); } } function classb(bcolor){ // classa.apply(this,array(bcolor)); classa.apply(this, arguments); // 这里使用上面的或者arguments都可以,arguments代表的是实参的类数组对象 } var obja = new classa('blue'); var objb = new classb('red'); obja.showcolor(); // blue objb.showcolor(); // red
function classa() {} classa.prototype.color = "blue"; classa.prototype.saycolor = function () { alert(this.color); }; function classb() {} classb.prototype = new classa(); // 这是关键
原型方式的神奇之处在于“classb.prototype = new classa()”代码行。这里,把 classb 的 prototype 属性设置成 classa 的实例。这很有意思,因为想要 classa 的所有属性和方法,但又不想逐个将它们 classb 的 prototype 属性进行手动链接。还有比把 classa 的实例赋予 prototype 属性更好的方法吗?
与对象冒充相似,子类的所有属性和方法都必须出现在 prototype 属性被赋值后,因为在它之前赋值的所有方法都会被删除。为什么?因为 prototype 属性被替换成了新对象,添加了新方法的原始对象将被销毁。所以,为 classb 类添加 name 属性和 sayname() 方法的代码如下:
function classb() { } classb.prototype = new classa(); classb.prototype.name = "zjy"; classb.prototype.sayname = function () { alert(this.name); };
测试代码如下:
var obja = new classa(); var objb = new classb(); obja.color = "blue"; objb.color = "red"; objb.name = "john"; obja.saycolor(); // blue objb.saycolor(); // red objb.sayname(); // john
// 父类 function classa(acolor){// 之所以方法通过原型链来定义是因为方法多数都是对象共享的,如果放在构造函数内部的话,多个实例化对象就会产生多个同样的方法,所以为了减少这样的浪费,将方法通过原型链定义,这样即满足了共享的原则也实现了重复利用不会浪费。不管在内部定义方法还是通过原型链定义,都可以通过其他构造函数的原型链继承到。 this.color = acolor; } classa.prototype.showcolor = function(){ //属性在构造函数内定义,方法通过原型定义 console.log(this.color); } // 子类 function classb(bcolor,name){ classa.call(this,bcolor); // 通过call()对象冒充的方式继承构造函数的属性 this.name = name; } classb.prototype = new classa(); // 通过原型链的方式继承构造函数的方法 classb.prototype.showname = function(){ console.log(this.name); }
测试代码如下:
var obja = new classa('blue'); var objb = new classb('red','tom'); obja.showcolor(); // blue objb.showcolor(); // red objb.showname(); // tom
如对本文有疑问, 点击进行留言回复!!
offset、client、scroll (width,height、left,top、X,Y)
网友评论