2

继承

原型链

  • 所谓言行链就是如果构造函数或对象A,A的原型指向构造函数或对象B,B的原型再指向构造函数或对象C,以此类推,最终的构造函数或对象的原乡指向Object的原型.由此形成一条链状结构,被称之为原型链

示例代码:

// 原型链
function A(){
    this.a = 'a';
}
// 通过构造函数创建对象
var a = new A();

function B(){
    this.b = 'b';
}
// 将B的原型指向对象a
B.prototype = a;
// 通过构造函数创建对象
var b = new B();

console.log(b.b);// b
console.log(b.a);// a

function C(){
    this.c = 'c';
}
// 将C的原型指向对象b
C.prototype = b;
// 通过构造函数创建对象
var c = new C();

console.log(c.c);// c
console.log(c.b);// b
console.log(c.a);// a

原型链代码分析图:
图片描述


只继承于原型

示例代码:

// 原型链
function A(){
    // 将自有属性改写为原型属性
    // this.a = 'a';
}
A.prototype.a = 'a';

function B(){
    // this.b = 'b';
}

// 将B的原型指向
B.prototype = A.prototype;

B.prototype.b = 'b';
/*B.prototype = {
    b : 'b'
}*/

function C(){
    this.c = 'c';
}
// 将C的原型指向
C.prototype = B.prototype;

var c = new C();
console.log(c.c);// c
console.log(c.b);
console.log(c.a);// a

原型链实现继承的问题

  1. 原型链实际上是在多个构造函数或对象之间共享属性和方法
  2. 常见子类的对象时,不能像父级的构造函数传递任何参数
  • 注意: 在实际开发中很少会单独使用原型链

示例代码:

// 原型链
function A(){
    // 将自有属性改写为原型属性
    // this.a = 'a';
}
A.prototype.a = 'a';

function B(){
    // this.b = 'b';
}

// 将B的原型指向
B.prototype = A.prototype;

B.prototype.b = 'b';

function C(){
    // this.c = 'c';
}
// 将C的原型指向
C.prototype = B.prototype;
C.prototype.c = 'c';

var c = new C();
console.log(c.c);// 调用结果为 c
console.log(c.b);// 调用结果为 b
console.log(c.a);// 调用结果为 a

var a = new A();

console.log(a.a);// 调用结果为 a
console.log(a.b);// 调用结果为 b
console.log(a.c);// 调用结果为 c

var b = new B();

console.log(b.a);// 调用结果为 a
console.log(b.b);// 调用结果为 b
console.log(b.c);// 调用结果为 c

原型式继承

  • 语法 : 定义一个函数 - 再将构造函数创建的对象返回,用于实现对象之间的继承

    • 参数

      • obj - 表示继承关系中的父级对象
      • prop - 对象格式,表示继承关系中的子级对象的属性和方法

示例代码:

function fn(obj,prop) {
    // 定义一个临时的构造函数
    function Fun() {
        // 遍历对象的属性和方法
        for(var attrName in prop){
            this[attrName] = prop[attrName];
        }
    }
    // 将函数的参数作为构造函数的原型
    Fun.prototype = obj;
    // 将构造函数创建的对象进行返回
    return new Fun();
}
var obj = {
    name : '皮卡丘'
};
// 调用函数
var result = fn(obj,{
    age : 26,
    sayMe : function () {
        console.log('一花一世界');
    }
});
console.log(result.age);// 调用结果为 26
result.sayMe();// 调用结果为 一花一世界

原型式竭诚另一种方法

示例代码:

 // 利用Object.create()
 var obj ={
    name : '皮卡丘'
 };
var newObj = Object.create(obj,{
    age : {
        value : 18
    },
    sayMe : {
        value : function () {
            console.log('一花一世界');
        }
    }
});
console.log(newObj.age);// 调用结果为 18
newObj.sayMe();// 调用结果为 一花一世界

借助构造函数

  • 可用过在子级的构造函数中调用父级的构造函数,来实现继承效果

示例代码:

// 定义父级对象的构造函数
function Parent() {
    this.parent = '嘎嘎嘎';
}

// 定义子级对象的构造函数
function Child() {
    // 调用父级对象的构造函数 - 使用apply()或call()方法
    Parent.call(this);
    this.child = '嚯嚯嚯';
}

// 创建子级对象
var child = new Child();
console.log(child);// 调用结果为 Child { parent: '嘎嘎嘎', child: '嚯嚯嚯' }

分析图:
图片描述


组合式继承

  • 就是将原型式继承和借助构造函数式继承有效的结合在一起

示例代码:

function Parent(){
    // 构造函数的自有属性
    this.name = '猪八戒';
}
// 构造函数的原型属性
Parent.prototype.age = 500 + '岁';

function Child(){
    // 继承父级构造函数中的自有属性
    Parent.call(this);

    this.job = '净坛使者';
}
// 继承父级构造函数中的原型属性
Child.prototype = Parent.prototype;

var child = new Child();

console.log(child.job);// 调用结果为 净坛使者
console.log(child.age);// 调用结果为 500岁
console.log(child.name);// 调用结果为 猪八戒

a达达
21 声望5 粉丝