js对象继承理解

js对象继承理解

一.原型链:

用法:把实例的父类给子函数的原型
缺点:
1》因为修改了obj1.arr后obj2.arr也变了,因为来自原型对象的引用属性里所有实例共享的
2》创建子类实例时,无法向父类构造函数传递参数

function Parent(){//父

    this.userName = "父函数";
    this.arr = [1,2,3];

}

function Child(){//子

    this.age = 18;

}

Child.prototype=new Parent(); 
//原型链===》核心:把实例的父类给子函数的原型


var obj1 = new Child();
var obj2 = new Child();
//console.log(obj1.userName);

obj1.arr[0] = "张三";

console.log(obj1.arr);//张三,2,3
console.log(obj2.arr);//张三,2,3

二.借用构造函数

核心:借父类的构造函数来增强子类实例,就是说,相当于复制了一份父类的属性或者方法给子类了

优点:
a)解决了子类实例共享父类引用属性的问题

b)创建子类实例时,可以向父类构造函数传递参数

缺点:
a)无法实现复用(不是共享的),每一个子类实例都有一个新的run函数,如果实例的对象多了,内存消耗过大

function Parent(name,arr){

    this.userName = name;
    this.arr = arr;
    this.run = function(){

        return 1111;
    }
}

function Child(name,arr){

    this.age = 18;

    Parent.call(this,name,arr);  //借用构造函数 ====》 核心代码

}

var obj1 = new Child("张三",[4,5,6]);
var obj2 = new Child("张三",[4,5,6]);

/*console.log(obj1.userName);
console.log(obj2.userName);*/

obj1.arr[0] = "你好构造函数";
console.log(   obj1.arr    );//你好构造函数,5,6
console.log(   obj2.arr    );//4,5,6

三.继承方式:(最常用的继承方式)

a)组合继承(原型链和借用构造函数组合

优点:
1》不存在引用属性共享的问题
2》可传递参数
3》方法可复用

缺点:(小瑕疵)
子类原型上有一份多余的父类实例的属性


function Parent(name,arr){

    this.userName = name;
    this.arr = arr;

}
Parent.prototype.run = function(){

    return "我是run方法";
};

function Child(name,arr){

        Parent.call(this,name,arr); 
        //借用构造函数===>核心语句    1》不能复用

}

Child.prototype=new Parent();  
//原型链===》核心语句     
//1》不能传递参数2》arr是引用属性,一个改变,互相影响

var obj1 = new Child("张三",[1,2,3]);
var obj2 = new Child("李四",[1,2,3]);

b)原型式继承(不要与原型链搞混了)

核心:用一个函数,生出来一个新的对象

优点:从已有对象繁衍出新的对象,不需要创建自定义类型

缺点:
1》原型的引用属性会互相影响(公用一个地址)
2》无法实现代码复用,属性是后添加的,都没用到函数封装

function fn(obj){ //用来生新对象的

    function F(){}//构造函数

    F.prototype=obj;  //F新的对象

    return new F();

}

var obj = {

    name:"张三",
    age:187

};

var obj1 = fn(obj);
var obj2 = fn(obj);
alert(obj1.name);//张三

ES5 之后用Object.create()实现原型式继承
在这里插入图片描述

c)寄生式继承

核心:创建新对象===》增强对象(添加属性或者方法)===》返回对象

(与工厂模式思想类似)


function fn(obj){

    var F = function(){};
    F.prototype=obj;
    return new F();
}

//原型式

function getSub(obj){
//寄生核心
   var clone = fn(obj);
   //新对象

    clone.attr1 = "class";
    clone.attr2 = "id";
    clone.brr = [1,2,3,];
    //增强

    return clone;
}
var o = {
    name:"张三",
    age:18,
    arr:[1,2,3]

};

var obj1 = new getSub(o);
var obj2 = new getSub(o);

obj1.brr[0] = "张三";
console.log(obj1.brr);//张三,2,3
console.log(obj2.brr);//1,2,3

d)寄生组合式继承

优点:修正组合继承的缺点,只使用一次构造函数
缺点:写法繁琐

function fn(obj){

    var F = function(){};
    F.prototype=obj;
    return new F();
}

function Sub(){

    this.str = "张三";
    //基本属性
    this.arr = [1,2,3];
    //引用属性

}
Sub.prototype.run = function(){

    return "共享的run方法";
};

function SubType(){
    Sub.call(this); //核心代码 ===》借用sub构造函数
}

var obj1 = fn(Sub.prototype);//核心===》传递原型
obj1.constructor = SubType;  //构造函数指向
Sub.prototype = obj1;   //实例对象赋值给sub原型


var obj2 = new SubType();
var obj3 = new SubType();

obj2.arr[0] = "张三";
console.log(obj2.arr);//张三,2,3
console.log(obj3.arr);//1,2,3

console.log(obj2.run == obj3.run);//true
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值