js继承 1.原型链继承 2.构造继承 3.实例继承 4.拷贝继承 5.组合继承 6.寄生组合继承

js继承
继承: 子类继承父类的属性和方法

1.原型链继承
通过下面两个内置对象了解到 js底层是通过原型链继承而来的
由外到内 通过__proto__属性连接 形成链式 就叫原型链
原型链继承是通过prototype属性实现继承
原型链继承的特点:
子类的实例继承自身的实例属性 也继承父类里面的构造属性和方法 父类的原型属性和方法
缺点:
1.不能继承子类的原型属性和方法
2.只能进行单继承 不能多继承
3.继承之后 原型对象上的属性全是共享
4.子类不能直接向父类传递参数

父类
function Person(a) {
this.name = a;
this.age = null;
this.sex = “男”;
this.sleep = function () {
return “睡觉”;
}
}
子类
Child.prototype = new Person(“zhang”);
function Child() {
this.job = null;
}
Child.prototype.weight=“200kg”;
Child.prototype.eat = function () {
return “吃饭”;
}

在原型链继承之后,给子类添加原型属性和方法,在继承后去添是直接添加给原型对象的
var child = new Child();
var child1 = new Child();
console.log(child, child1);
在这里插入图片描述

1.原型链继承之后
console.log(Child.prototype);//子类的原型对象指向父类
如果没有原型链继承 子类的原型对象指向自身prototype

2.子类对象显示的既是自身也是父类
console.log(child instanceof Child); //true
console.log(child instanceof Person); //true

console.log(child.proto);// Person
console.log(child.proto.proto); //Person 的原型对象
console.log(child.proto.proto.proto); //Object
console.log(child.proto.proto.proto.proto);//Object 的 proto null

2.构造继承
通过使用call apply 来实现继承,直接在子类的内部去写call apply
优点:可以实现多继承,可以向父类传递参数
缺点: 构造继承 ,无法继承父类的原型属性和方法,子类的实例是本身不是父类
function Animal() {
this.name = arguments[0];
this.sleep = function () {return “睡觉”;} }
function Type() { this.type = arguments[0];}
function Dog(n, s, t) {
this.sex = s;
this.eat = function () {
return “吃饭”;}
//下面写构造继承
Animal.call(this, n);
Type.apply(this, [t]);}

Dog.prototype = {
constructor: Dog,
sleep: function () { }}

var dog = new Dog(“小花”, “公”, “犬科”);
console.log(dog);
输出结果

//子类对象显示的是本身不是父类
console.log(dog instanceof Dog);//true
console.log(dog instanceof Animal);//false

//子类的原型对象
console.log(Dog.prototype);//{constructor: ƒ, sleep: ƒ}
console.log(dog.proto);//{constructor: ƒ, sleep: ƒ}
console.log(typeof dog.proto.proto);//Object

3.实例继承
实例继承
在子类内部直接构造父类的实例 直接new父类
优点:不限制调用方式 可以向父类传递参数
缺点: 不能实现多继承
不能拿到子类构造属性和方法
子类的实例不是本身而是父类

function Person(n,s){
this.name=n;
this.sex=s;
this.sleep=function (){
return “睡觉”;}}

function Child(n,s){
this.eat=function (){ }
return new Person(n,s);}
//子类实例有两种写法
1.var child=Child(“小米”,“男”);
console.log(child);
2.var child1=new Child(“小米”,“男”);
console.log(child1);
在这里插入图片描述
子类对象显示的是父类不是本身
console.log(child instanceof Child);//false
console.log(child instanceof Person);//true

console.log(Child.prototype);//自身的原型对象
console.log(child.proto);//Person的原型对象
console.log(child.proto.proto);//Object 的原型对象
console.log(child.proto.proto.proto);//null

4.拷贝继承
拷贝继承
将父类里面的方法和属性 拷贝给子类
优点:
支持多继承 子类对象实例是本身不是父类,可以向父类传递参数
缺点: 在继承的时候 ,不断new,占内存

function Animale(){
this.name=arguments[0];
this.sleep=function (){
return “睡觉”;
}
}

function Type(){
this.type=arguments[0];
}

function Cat(n,s,t){
this.sex=s;
this.eat=function (){
return “吃饭”;
}
//拷贝父类里面的属性和方法 拷贝给prototype
//先实例化父类对象
var animale=new Animale(n);
for(var key in animale)
{Cat.prototype[key]=animale[key]; }
var type=new Type(t);
for(var key in type)
{ Cat.prototype[key]=type[key];}
}
var cat=new Cat(“小花”,“公”,“猫科”);
console.log(cat);
在这里插入图片描述
console.log(cat.proto);
在这里插入图片描述

//子类对象显示的是本身 不是父类
console.log(cat instanceof Cat);//true
console.log(cat instanceof Animale);//false
console.log(cat instanceof Type);//false

5.组合继承
组合继承 原型链继承+构造继承相互弥补自己的缺点

可以实现多继承
可以像父类传递参数
没有实现原型对象属性的共享

function Person(n){
this.name=n;
this.eat=function (){
return this.name+“吃饭”;
}
}
Person.prototype={
constructor:Person,
color:null
}
function Child(a,s,n){
this.age=a;
this.sex=s;
this.sleep=function (){
return “睡觉”;
}
Person.call(this,n); //构造继承 只能获取到父类的属性和方法 拿不到原型属性和方法

Child.prototype.work=“学生”;
Child.prototype=new Person(“heihei”);//注意这 这里没传值
var child=new Child(12,“男”,“花花”);
var child1=new Child(12,“女”,“小红”);
console.log(child1);
在这里插入图片描述

子类对象显示的既是本身也是父类
console.log(child instanceof Child);//true
console.log(child instanceof Person);//true

6.寄生组合继承
处理组合继承 的缺点 避免调用两次父类的构造函数
原理是 将父类的原型对象给一个空对象的prototype 再把空对象和子类的原型对象关联

function Person(){
this.name=null;
this.sleep=function (){
return this.name+“睡觉”;
}
}
Person.prototype={
constructor:Person,
color:null
}

function Child(){
this.age=null;
this.eat=function (){
return this.name+“吃饭”;
}
Person.call(this);
}
//开始寄生
(function (){
var fn=function (){};
fn.prototype=Person.prototype;
Child.prototype=new fn();
})();
var child=new Child();
console.log(child);
在这里插入图片描述

子类对象显示的既是本身也是父类
console.log(child instanceof Child);//true
console.log(child instanceof Person);//true

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值