资讯专栏INFORMATION COLUMN

JavaScript面向对象编程——继承

desdik / 472人阅读

摘要:想要解决这样的问题的话,可以借助构造函数也可以叫做伪造对象或经典继承。通过借助构造函数实现对实例对象的属性和继承。

原型链 原型链是什么

构造函数或构造器具有prototype属性 对象具有__proto__属性 这就是之前学习的原型
如果构造函数或对象A A的原型指向构造函数或对象B B的原型在指向构造函数或对象C 以此类推 最终的构造函数或对象的原型指向Object的原型 由此形成一条链状结构 被称之为原型链
按照上述的描述 在B中定义的属性或方法 可以直接在A中使用并不需要定义 这就是继承 它允许每个对象来访问其原型链上的任何属性或方法。
原型链是ECMAScript标准中指定的默认实现继承方式。

// 原型链
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
只继承于原型

处于对效率的考虑,尽量的将属性和方法添加到原型上。
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";
/*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
原型链的问题

原型链虽然很强大,用他可以实现JavaScript中的继承,但同时也存在着一些问题。
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);
console.log(a.b);
console.log(a.c);

var b = new B();

console.log(b.a);
console.log(b.b);
console.log(b.c);
继承 原型式继承

所谓的原型式继承,就是定义一个函数,该函数中创建一个临时性 的构造函数,将作为参数传入的对象,作为这个构造函数的原型,左后返回这个构造函数的实例对象。

/*
    定义一个函数 - 用于实现对象之间的继承
    * 参数
      * obj - 表示继承关系中的父级对象
      * prop - 对象格式,表示继承关系中的子级对象的属性和方法
  */
function fn(obj, porp){
    // 定义一个临时的构造函数
    function Fun(){
        // 遍历对象的属性和方法
        for (var attrName in porp) {
            // var attrValue = porp[attrName];
            this[attrName] = porp[attrName];
        }
    }
    // 将函数的参数作为构造函数的原型
    Fun.prototype = obj;
    // 将构造函数创建的对象进行返回
    return new Fun();
}
var obj = {
    name : "张无忌"
}
// 调用函数
var result = fn(obj, {
    age : 18,
    sayMe : function(){
        console.log("this is function");
    }
});
console.log(result.age);
result.sayMe();

注意;原型式继承具有与原型链相同的问题。

借助构造函数

无论是原型链还是原型式继承,都具有相同的问题。想要解决这样的问题的话,可以借助构造函数(也可以叫做伪造对象或经典继承)。
这种方式实现非常简单,就是在子对象的构造函数中调用父对象的构造函数,具体可以通过调用apply()和call()方法实现。
apply()和call()方法允许传递指定某个对形象的 this。对于继承来说,可以实现子对象构造函数中调用父对象的构造函数时,将子对象的this和父对象的this绑定在一起。

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

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

    this.child = "child";
}
// 创建子级对象
var child = new Child();
console.log(child);
组合方式继承

组合继承,也佳作为经典继承,指的是将原型链或原型式继承和借助构造.函数的技术组合在一起,发挥二者长处的一种继承方式。
1.使用原型链或原型式继承实现对原型的属性和方法的继承。
2.通过借助构造函数实现对实例对象的属性和继承。
这样既通过在原型定义方法实现了函数的重用,又保证每个对象都有自己的专有属性。

function Parent(){
    // 构造函数的自有属性
    this.name = "张无忌";
}
// 构造函数的原型属性
Parent.prototype.age = 18;

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

    this.job = "教主";
}
// 继承父级构造函数中的原型属性
Child.prototype = Parent.prototype;

var child = new Child();

console.log(child.job);
console.log(child.age);
console.log(child.name);

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/108359.html

相关文章

  • SegmentFault 技术周刊 Vol.32 - 七夕将至,你的“对象”还好吗?

    摘要:很多情况下,通常一个人类,即创建了一个具体的对象。对象就是数据,对象本身不包含方法。类是相似对象的描述,称为类的定义,是该类对象的蓝图或原型。在中,对象通过对类的实体化形成的对象。一类的对象抽取出来。注意中,对象一定是通过类的实例化来的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 马上就要到七夕了,离年底老妈老爸...

    李昌杰 评论0 收藏0
  • SegmentFault 技术周刊 Vol.32 - 七夕将至,你的“对象”还好吗?

    摘要:很多情况下,通常一个人类,即创建了一个具体的对象。对象就是数据,对象本身不包含方法。类是相似对象的描述,称为类的定义,是该类对象的蓝图或原型。在中,对象通过对类的实体化形成的对象。一类的对象抽取出来。注意中,对象一定是通过类的实例化来的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 马上就要到七夕了,离年底老妈老爸...

    Lyux 评论0 收藏0
  • SegmentFault 技术周刊 Vol.32 - 七夕将至,你的“对象”还好吗?

    摘要:很多情况下,通常一个人类,即创建了一个具体的对象。对象就是数据,对象本身不包含方法。类是相似对象的描述,称为类的定义,是该类对象的蓝图或原型。在中,对象通过对类的实体化形成的对象。一类的对象抽取出来。注意中,对象一定是通过类的实例化来的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 马上就要到七夕了,离年底老妈老爸...

    AaronYuan 评论0 收藏0
  • JavaScript面向对象编程——面向对象

    摘要:面向对象面向对象的概述面向对象是什么面向对象编程的全称是,简称。面向对象编程是用抽象方式创建基于现实世界模型的一种编程。面向对象编程可以看做是使用一系列对象相互协作的软件设计。面向对象编程的山歌主要的特征是封装继承多态。 面向对象 面向对象的概述 面向对象是什么 面向对象编程的全称是Object Oriented Programming,简称OOP。面向对象编程是用抽象方式创建基于现实...

    SimonMa 评论0 收藏0
  • JavaScript面向对象编程学习笔记---概念定义

    摘要:子类继承自父类的方法可以重新定义即覆写,被调用时会使用子类定义的方法什么是多态青蛙是一个对象,金鱼也是一个对象,青蛙会跳,金鱼会游,定义好对象及其方法后,我们能用青蛙对象调用跳这个方法,也能用金鱼对象调用游这个方法。 1、专用术语 面向对象编程程序设计简称:OOP,在面向对象编程中常用到的概念有:对象、属性、方法、类、封装、聚合、重用与继承、多态。 2、什么是对象? 面向对象编程的重点...

    mikasa 评论0 收藏0
  • 面向对象JavaScript

    摘要:是完全的面向对象语言,它们通过类的形式组织函数和变量,使之不能脱离对象存在。而在基于原型的面向对象方式中,对象则是依靠构造器利用原型构造出来的。 JavaScript 函数式脚本语言特性以及其看似随意的编写风格,导致长期以来人们对这一门语言的误解,即认为 JavaScript 不是一门面向对象的语言,或者只是部分具备一些面向对象的特征。本文将回归面向对象本意,从对语言感悟的角度阐述为什...

    novo 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<