JS面向对象(二)—继承

在面向对象的语言中,如Java,它的继承是单继承的,利用的是extends关键字实现的,而在JavaScript中同样是没有这个关键字的,但是通过以下的方式,我们还是可以模仿出继承来的。


原型对象
当然在说这个继承之前,必须要明确的就是原型对象是什么?当我们在创建了一个新函数的时候,该函数就会拥有一个prototyp属性,这个属性是指向函数的原型对象的。在原型对象中,会自动拥有一个constructor属性,也就是所说的构造函数,而constructor所指向的就是该函数本身。总结起来就是,每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例对象中有一个指向原型对象的内部指针。


JS实现继承的方法:

1. 原型继承

使用这种方法的时候,通过new SuperType()调用了父类的构造方法,这种就是使用了JS中的原型链,父类中含有value被 SubType的所有实例所共享,形象点描述,就是有一根绳子A端和B端,然后在绳子的A端再“并联”拉上多根绳子分别为C1,C2…..Ci,那么很显然,通过C1,C2…..Ci找到的B端就是唯一的,如果Ck对B端进行修改,那么其他C端访问的B端就是改变了的。当然在创建子类的时候,是不可能向父类的构造函数中去传递参数的。

function SuperType(){
    this.value = 10;
}

SuperType.prototype.getSuperValue = function() {
    return this.value;
};
SuperType.prototype.setSuperValue = function(value) {
    this.value = value;
};

function SubType(){ }
SubType.prototype = new SuperType();

SubType.prototype.getSubValue = function() {
    return 0;
};

var instance = new SubType();
alert(instance.getSubValue);  //10

2. 类继承

类继承也可以说是用构造函数去继承,简单的说就是在子类的构造函数内部中调用父类的构造函数,

function SuperClass(){
    this.array = [34, 57, 68, 99];
}
function SubClass(){
    SuperClass.call(this);
}
var instance1 = new SubClass();
instance1.array.push(89);
alert(instance1.array);  //34, 57, 68, 99, 89
var instance2 = new SubClass();
alert(instance2.array);  //34, 57, 68, 99

通过上面的代码运行结果我们可以看出,利用这种方法每个实例会独自拥有一个array


3. 组合继承

所谓组合继承,就是将前面所说的“原型继承”和“类继承”融合起来,通过“原型继承”实现对原型属性和方法的继承,通过“类继承”实现对父类属性的继承,让其独自拥有。

function SuperType(color){
    this.value = 10;
    this.color = color;
},
SuperType.prototype.getSuperColor = function() {
    alert(this.color);
};
function SubType(color){    
    SuperType.call(this, color);
    this.name = "sub";
}
SubType.prototype = new SuperType();
SubType.prototype.getSubName = function() {
    alert(this.name);
};

var instance = new SubType("green");
alert(instance.getSuperColor);  //green

4. 模拟extjs底层继承方式

我个人还是比较喜欢这种方式来实现继承的(也算是对组合模式的一个补充),对这个函数进行如下分析,1、创建一个空对象 2、对空函数的原型与sup的原型进行转换 3、sup实现原型继承 4、还原子类的构造器(constructor),这种操作在之前的方法自己害怕并没有涉及到 5、保存父类的原型对象,作用呢?为了解耦,也为了方便获得父类的原型对象 6、判断父类的原型对象的构造器

function  extend(sub, sup){
    var F = new Function();
    F.prototype = sup.prototype;
    sub.prototype = new F();
    sub.prototype.constructor = sub;
    sub.superClass = sup.prototype;

    if(sup.prototype.constructor == Object.prototype.constructor){
        sup.prototype.constructor = sup;
    }
}

如何使用呢?看下面的例子

function Parent(name, age){
    this.name = name;
    this.age = age;
}
Parent.prototype.sayHello = function(){
    alert('我是父类');
};
function Boy(name, age, sex){
    Boy.superClass.constructor.call(this, name, age);
    this.sex = sex;
}
extend(Boy, Parent); 
Boy.prototype.sayHello = function(){
    alert('我是子类');
}
var b = new Boy('zhang', 20, '男');

5. Object.create()的使用

首先呢,这个方法兼容的浏览器有IE9+、FireFox 4+、Safari 5+、Opera 12+、Chrome
它的作用规范了原型式继承,它的介绍在上篇博客中已经讲述,这里就不再重复。下面用个例子来具体说明

var newCar = new Car("benz", 18);
alert(newCar.price);


var person = {
    name : "Dear_mr",
    friend : "shelby", "Greg", "Linda"
};

var onePerson = Object.create(person);
var anotherPerson = Object.create(person, {
    name:{
        value:"MR_"
    }
});

如何使用呢?看下面的例子

var person = {
    name : "Dear_mr",
    friend : "shelby", "Greg", "Linda"
};

var onePerson = Object.create(person);
var anotherPerson = Object.create(person, {
    name:{
        value:"MR_"
    }
});

第二参数就是指定属性从而实现覆盖,个人觉得这种方法和利用类继承对于“属性共享”的结果是相似的。
当然对于这个Object.create(),我们也可以自己写一个objec函数

function object(o){
    Function F(){};
    F.prototype = o;
    return new F();
}
总结:对于继承,其实关键是在于原型链以及"类"(构造函数)的理解,所谓的继承方法就是通过这两个东西所实现的,利用原型,和利用构造函数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值