【一】通过对象的原型添加属性两种方式
function Product(name,color){
this.name = name;
this.color = color;
this.whatAreYou = function(){
return 'this is a '+this.color+' '+this.name;
};
}
//第一种
Product.prototype.price = 200;
Product.prototype.rating = 3;
Product.prototype.getInfo = function(){
return "等级:"+this.rating+"--价钱"+this.price;
}
//第二种
Product.prototype={
price:6888,
rating:3,
getInfo:function(){
return "等级:"+this.rating+"--价钱"+this.price;
}
}
【二】原型链继承
function Shape(){
this.name = 'Shape';
this.toString=function(){
return this.name;
}
}
function TwoDShape(){
this.name = '2D shape';
}
function Triangle(side,height){
this.name='Triangle';
this.side=side;
this.height = height;
this.getArea=function(){
return this.side*this.height/2;
}
}
//继承
TwoDShape.prototype = new Shape();
Triangle.prototype = new TwoDShape();
//重置constructor 属性 (这里必须重置构造器,否则,TwoDShape原型的构造器会变成全局的Object 对象)
TwoDShape.prototype.constructor=TwoDShape;
Triangle.prototype.constructor=Triangle;
//创建对象
var myTriangle = new Triangle(5,10);
console.log(myTriangle.getArea());
//获取对象的构造器
console.log(myTriangle.constructor);
//对象实例化自
console.log(myTriangle instanceof Triangle);//true
console.log(myTriangle instanceof TwoDShape);//true
console.log(myTriangle instanceof Shape);//true
//检测对象是否在原型链上
console.log(Shape.prototype.isPrototypeOf(myTriangle));//true
console.log(TwoDShape.prototype.isPrototypeOf(myTriangle));//true
console.log(Triangle.prototype.isPrototypeOf(myTriangle));//true
console.log(Object.prototype.isPrototypeOf(myTriangle));//true
console.log(String.prototype.isPrototypeOf(myTriangle));//false
【三 】 继承优化:只继承原型的方案
function Shape(){};
Shape.prototype.name = 'shape';
Shape.prototype.toString = function(){
return this.name;
}
function TwoDShape(){};
TwoDShape.prototype = Shape.prototype;
TwoDShape.prototype.constructor=TwoDShape;
TwoDShape.prototype.name = '2D Shape';
function Triangle(side,height){
this.side = side;
this.height = height;
}
Triangle.prototype = TwoDShape.prototype;
Triangle.prototype.constructor=Triangle;
Triangle.prototype.name = 'Triangle';
Triangle.prototype.getArea=function(){
return this.side*this.height/2;
}
var my = new Triangle(5,10);
console.log(my.getArea(5,10));
console.log(my.toString());
//需要注意:只继承原型会带来一个问题
var s = new Shape();
console.log(s.name);
//这里输出的结果为 Triangle 而不是 shape,这是因为只继承原型时name属性指向是同一个,
//所以子类Triangle修改name属性时整个原型链上的name属性值都会被修改成同一个值
//上述的问题可以通过临时构造器来解决,如下所示
function Shape(){};
Shape.prototype.name = 'Shape';
Shape.prototype.this.toString=function(){
return this.name;
}
function TwoDShape(){};
//声明临时构造器
var F= function(){};
F.prototype = Shape.prototype;
TwoDShape.prototype = new F();
TwoDShape.prototype.construtor = TwoDShape;
TwoDShape.prototype.name = '2D Shape';
function Triangle(side,height){
this.side = side;
this.height = height;
}
var F = function(){};
F.prototype = TwoDShape.prototype;
Triangle.prototype = new F();
Triangle.prototype.name = 'Triangle';
Triangle.prototype.getArea=function(){
return this.side*this.height/2;
}
var my = new Triangle(5,10);
console.log(my.getArea(5,10));
console.log(my.toString());
console.log(my._proto__._proto__._proto__.construtor);
var s = new Shape();
console.log(s.name);
【四】继承封装
//---------第一种-----------
function extend(Child, Parant) {
//声明临时构造器
var F = function() {};
F.prototype = Parant.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
Child.uber = Parant.prototype; //uber 代表的是指向当前对象父级原型的引用,实现继承
}
function Shape() {}
Shape.prototype.name = 'Shape';
function TwoDShape() {};
TwoDShape.prototype.name = 'TwoDShape';
extend(TwoDShape, Shape);
function Triangle(side, height) {
this.side = side;
this.height = height;
}
Triangle.prototype.name = 'Triangle';
extend(Triangle, TwoDShape);
Triangle.prototype.getArea = function() {
return this.side * this.height / 2;
}
//------------第二种-----------------
< pre name = "code"
class = "javascript" >
var o = {};
function extendCopy(p) {
var c = {};
for (var i in p) {
c[i] = p[i];
}
c.uber = p;
return c;
}
var Shape = { name: 'Shape', toString: function() {
return this.name; } };
var TwoDShape = extendCopy(Shape);
TwoDShape.name = '2d Shape';
TwoDShape.toString = function() {
return this.uber.toString + '--' + this.name; }
var Triangle = extendCopy(TwoDShape);
Triangle.name = 'triangle';
Triangle.getArea = function() {
return this.side * this.height / 2; }
Triangle.side = 5;
Triangle.height = 8;
console.log(Triangle.getArea());
//----------第三种----------
function objectPlus(o,stuff){
//声明临时构造器
function F(){};
F.prototype=o;
var n = new F();
n.uber = o;//uber 代表的是指向当前对象父级原型的引用,实现继承
//拷贝父类属性
for (var i in stuff) {
n[i]=stuff[i];
}
return n;
}
var Shape={
name:'Shape',
toString:function(){
return this.name;
}
};
var TwoDShape = objectPlus(Shape,{
name:'2D Shape',
toString:function(){
return this.uber.toString()+'---'+this.name;
}
});
var Triangle = objectPlus(TwoDShape,{
name:'triangle',
getArea:function(){
return this.side*this.height/2;
}
side:0
height:0
});
【五】多重继承
function multiExtend(){
var n = {},stuff,j=0,len = arguments.length;
for (j=0;j<len;j++) {
stuff = arguments[j];
for (var i in stuff) {
n[i]=stuff[i];
}
}
return n;
}
var Shape={
name:'Shape',
toString:function(){
return this.name;
}
};
var TwoDShape = {
name:'2D Shape',
test:'this is test'
};
var Triangle = multiExtend(Shape,TwoDShape,{
name:'triangle',
getArea:function(){
return this.side*this.height/2;
}
side:5,
height:10
});