JavaScript实现继承的五种方式

JavaScript实现继承的五种方式

1.##经典继承
实现原理: 在子类的构造函数内部调用超类型构造函数。
通过使用apply()和call()方法在新创建的对象上执行构造函数

缺点: 方法都在构造函数中定义,没有用到函数的复用。
在超类型的原型中定义的方法,对子类是不可见的,所以导致所有的类型都只能使用构造函数

function SuperType(){
      this.number =[1,2,6,8,9];
}
function SubType(){
   //继承 SuperType
   SuperType.call(this);
   }
   var obj = new SubType();
   obj.number.push(7);
   console.log(obj.number);// 1,2,6,8,9,7

   var obj2 = new SubType();
   console.log(obj2.number) // 1,2,6,8,9

2.组合继承(伪经典继承)

实现原理: 使用原型链实现对原型属性和方法的继承,通过借用构造函数来实习实例属性的继承
不但通过原型定义方法实习了函数的复用,又保证每个实例 都有自己的数组
它避免了原型链和借用构造函数的缺点,融合了他们的优点,成为JavaScript常用的继承模式

<script>
/**
 *
 *      组合继承
 *          call            继承属性
 *          prototype       继承方法
 *
 * */

/* Person 构造函数 */
function Person(name, age) {
    this.name = name;
    this.age = age;
}

Person.prototype.sayHi = function () {
    console.log('我是' + this.name);
};

Person.prototype.sayAge = function () {
    console.log('我今年' + this.age);
};


// 学生对象和人对象其实有很多重复
// 所以我们考虑 <学生对象> 从 <人对象> 上<继承>过来一些基本的属性
function Student(name, age, classNo) {
    /*
     *    call (打电话)借用一下 Person 构造函数
     *       第一个参数:调用该函数的那个对象
     *       后面的参数:作为实参传过去
     **/
    Person.call(this, name, age);     // 借用构造函数只能借用属性
    this.classNo = classNo;
}

/* 改变1 →: 尽管是空对象,但是空对象也有原型,间接继承了原型的方法  */
// new Person()   实例化一个空对象,其实我们不是用空对象的属性,而是用了对象的原型
Student.prototype = new Person();
/* 改变2 →: 这行代码写不写都不影响继承,写了显得更专业,更规范  */
// 由于上一行代码把原型改变了,constructor 没了,所以我们人为再添加一个 constructor
Student.prototype.constructor = Student;

// console.log(Student.prototype);

var p1 = new Person('大树', 48);
var stu1 = new Student('小成', 18, 313);


// 后面给 Person 添加的方法,看看后面能不能调用
Person.prototype.say666 = function(){
    console.log(666);
};

console.log(p1);
console.log(stu1);
stu1.sayAge();

/*
*     Student 的原型方法继承自 Person
*         p1 能调用 say666,sayHi,sayAge
*         stu1 也能调用 say666,sayHi,sayAge
* */
p1.say666();
stu1.say666();

console.log(stu1 instanceof Student);   // true
console.log(stu1 instanceof Person);    // true
console.log(stu1 instanceof Object);    // true
</script>

3.原型继承
思路: 借助原型可以基于已有的对象创建对象,同时还不必因此创建自定义类型
在object()函数内部,创建一个临时的构造函数,然后将传入的对象作为这个构造函数的原型,最好返回临时的新实例

Function obj(){
Function F(){
F.prototype = o;
Return new F();
}
  1. 寄生继承
    思路: 创建一个仅仅用于封装继承过程的函数,该函数在内部一某种方式来增强对象,最后再像真的是它做了所有的工作一样返回对象

缺点: 使用寄生式继承来为对象添加函数,会由于不能做到函数的复用二降低效率,这点和构造函数模式相似

Function createAonter (original){
	var clone = object(original); // 通过构造函数创建一个新对象
	Clone.sayHi = function(){// 用某种方式来增强这个函数
	Alert('hi');
	}
	Return clone;// 返回这个对象
}

5.寄生组合式继承 类的继承用的就是这个
思路: 通过借用构造函数来继承属性,通过原型链的混成形式来继承方法
本质上就是 使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型
目前来说 算是最理想的继承方式了 extend() 就是用了这种方式

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值