1. 对象冒充
a. 直接实现 例:
function ClassA(sColor) ...{
this.color = sColor;
this.sayColor = function () ...{
alert(this.color);
};
}
function ClassB(sColor, sName) ...{
this.newMethod = ClassA;
this.newMethod(sColor);
delete this.newMethod;
this.name = sName;
this.sayName = function () ...{
alert(this.name);
};
}
var objA = new ClassA("red");
var objB = new ClassB("blue", "Nicholas");
objA.sayColor();
objB.sayColor();
objB.sayName();
所有的新属性和新方法都必须在删除了新方法的代码行后定义,否则可能会覆盖超类的相关属性和方法
b. 用Call()方法实现
function ClassA(sColor) ...{
this.color = sColor;
this.sayColor = function () ...{
alert(this.color);
};
}
function ClassB(sColor, sName) ...{
//this.newMethod = ClassA;
//this.newMethod(color);
//delete this.newMethod;
ClassA.call(this, sColor);
this.name = sName;
this.sayName = function () ...{
alert(this.name);
};
}
var objA = new ClassA("red");
var objB = new ClassB("blue", "Nicholas");
objA.sayColor();
objB.sayColor();
objB.sayName();
c. 用Apply()方法实现
function ClassA(sColor) ...{
this.color = sColor;
this.sayColor = function () ...{
alert(this.color);
};
}
function ClassB(sColor, sName) ...{
//this.newMethod = ClassA;
//this.newMethod(color);
//delete this.newMethod;
ClassA.apply(this, arguments);
this.name = sName;
this.sayName = function () ...{
alert(this.name);
};
}
var objA = new ClassA("red");
var objB = new ClassB("blue", "Nicholas");
objA.sayColor();
objB.sayColor();
objB.sayName();
call()有点类似于java中的反射机制,b.call(a,c)用汉语描述可以这样理解:对象a调用b方法,c是b方法的参数。apply类似,不过apply第二个参数是一个数组。
2. 原型链
第二种继承方式是原型方式,所谓原型方式的继承,是指利用了prototype或者说以某种方式覆盖了prototype,从而达到属性方法复制的目的。例
function ClassA() ...{
}
ClassA.prototype.color = "red";
ClassA.prototype.sayColor = function () ...{
alert(this.color);
};
function ClassB() ...{
}
ClassB.prototype = new ClassA();
ClassB.prototype.name = "";
ClassB.prototype.sayName = function () ...{
alert(this.name);
};
var objA = new ClassA();
var objB = new ClassB();
objA.color = "red";
objB.color = "blue";
objB.name = "Nicholas";
objA.sayColor();
objB.sayColor();
objB.sayName();
子类的所有属性和方法都必须出现在prototype属性被赋值后,因为在它之前赋值的所有方法都会被删除,因为prototype属性被替换成了新对象,添加了新方法的原始对象将删除。原型链不支持多重继承。记住,原型链会用另一类型的对象重写类的prototype属性。
上面两种方法的缺点:
对象冒充的缺点是:构造对象时必须使用构造函数方式,构造函数方式的缺点是:为所有的对象的所有属性和方法都建立一个副本,为对象的属性建立副本是没问题的,但为所有的方法也建立副本就没必要,这样会浪费内存,一个类的所有对象共享一个 方法的副本就行了。
原型链的缺点是:建立对象是必须使用无参的构造函数,不能使用带参的构造函数。因为对子类prototype域的修改是在声明子类对象之后才能进行,用子类构造函数的参数去初始化父类属性是无法实现的。
3. 混合方式
混合方式类似于前面文章javascript对象类型的混合方式,用对象冒充继承构造函数的属性,用原型链继承prototype对象的方法。例
function ClassA(sColor) ...{
this.color = sColor;
}
ClassA.prototype.sayColor = function () ...{
alert(this.color);
};
function ClassB(sColor, sName) ...{
ClassA.call(this, sColor);
this.name = sName;
}
ClassB.prototype = new ClassA();
ClassB.prototype.sayName = function () ...{
alert(this.name);
};
var objA = new ClassA("red");
var objB = new ClassB("blue", "Nicholas");
objA.sayColor();
objB.sayColor();
objB.sayName();
JS继承机制
最新推荐文章于 2019-07-31 21:01:54 发布