资讯专栏INFORMATION COLUMN

js面向对象浅谈(三)

awkj / 2462人阅读

摘要:还有一个问题,就是不能在创建子类性时,像父类型的构造函数传递参数。组合继承将原型链和借用构造函数组合到一起,发挥两者之长的一张继承模式,下面来看个例子。组合继承最大的问题是无论在什么情况下,都会调用两次父类型构造函数。

继承

继承是面向对象语言中特别重要的概念,js的继承主要是靠原型链实现的。

原型链!!!

看到我给标题打了三个叹号吗,这里真的很重要!这里真的很重要!这里真的很重要!js描述了原型链的概念,并将原型链做为实现继承的主要方法,其基本思想是让一个引用类型继承另一个引用类型的属性和方法。看代码

function SuperType() {
    this.property = true;
}

SuperType.prototype.getSuperValue = function () {
    return this.property;
}

function SubType () {
    this.Subproperty = false;
}

SubType.prototype = new SuperType();

SuperType.prototype.getSubValue = function () {
    return this.subproperty;
}

var instance = new SubType();
console.log(instance.getSuperValue())

下面继续上我的灵魂画作:


话不多说,原理都在图里,相信聪明的你们早就懂了。在上面的代码中,我们没有使用SubType默认提供的原型,而是给它换了一个新原型。这个原型是父类的实例,新原型具有全部属性和方法,现在也存在于子类的原型中了。

通过原型链,本质上扩展了原型搜索机制。在instance.getSuperValue()调用会经历三个搜索步骤

搜索实例

搜索原型对象

搜索父类原型对象

一环一环向上搜索直到原型链末端才会停下来。但是我们子类上的valueOf这些方法是哪里来的呢?父类并没有显示声明这些方法啊下面继续上图。

SubType继承了SuperType,SuperType继承了Object,当调用instance.valueOf()方法时,实际上调用的是保存在Object.prototype中的方法。

原型链的问题

原型链这么强大,同样也会造成问题。最主要的问题来自于包含引用类型的原型。引用类型的原型属性会被虽有实例共享,在通过原型来实现继承时,原型会变成另一个类型的实例,原先的实例属性也就顺理成章变成来现在的原型属性。

function SuperType () {
    this.colors = ["red", "blue", "green"];
}

function SubType () {
    
}


SubType.prototype = new SuperType();

var instance1 = new SubType();

instance1.colors.push("black");

console.log(instance1.colors)

var instance2 = new SubType();

console.log(instance2.colors)

还有一个问题,就是不能在创建子类性时,像父类型的构造函数传递参数。所以我们一般很少多带带使用原型链。

借用构造函数
function SuperType () {
    this.colors = ["red", "blue", "green"];
}

function SubType () {
    // 继承了 SuperType
    SuperType.call(this);
}

var instance1 = new SubType();

instance1.colors.push("black");

console.log(instance1.colors);


var instance2 = new SubType();
console.log(instance2.colors);

也可以传递参数

 function SuperType (name) {
    this.name = name;
}

function SubType () {
    // 继承了 SuperType
    SuperType.call(this, "李小花");
}

var instance1 = new SubType();
console.log(instance1.name)
但是这样问题也很明显,方法只能定义在构造函数中定义,定义在原型上的方法无法继承。借用构造函数的技术也很少使用。

组合继承
将原型链和借用构造函数组合到一起,发挥两者之长的一张继承模式,下面来看个例子。

   function SuperType (name) {
    this.name = name;
}

SuperType.prototype.sayName = function() {
    console.log(this.name)
};

function SubType (name, age) {
    // 继承了 SuperType
    SuperType.call(this, name);

    this.age = age;
}
SubType.prototype = new SuperType();

var instance1 = new SubType();
console.log(instance1.name)


组合继承是 js最常用的继承模式。

寄生组合式继承

组合继承是最常用的继承模式,但也不是没有缺点。组合继承最大的问题是无论在什么情况下,都会调用两次父类型构造函数。

 function SuperType (name) {
    this.name = name;
}

SuperType.prototype.sayName = function() {
    console.log(this.name)
};

function SubType (name, age) {
    // 继承了 SuperType
    SuperType.call(this, name);  //第二次调用

    this.age = age;
}
SubType.prototype = new SuperType();  // 第一次调用

var instance1 = new SubType();
console.log(instance1.name)

我们不必为了指定子类型的原型调用超类型的构造函数,我们所需要的不过是超类型原型的一个副本而已。

function SuperType (name) {
    this.name = name;
    this.color = ["red", "blue", "green"];
}

SuperType.prototype.sayName = function() {
    console.log(this.name);
};

function SubType (name, age) {
    SuperType.call(this, name);
    this.age = age;
}

SubType.prototype = Object.create(SuperType.prototype);

SubType.prototype.constructor = SubType

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

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

相关文章

  • 浅谈PHP面向对象编程

    摘要:一面向对象编程基础实践通过对象的编程方式,可将实现生活中的一切事物以对象的形式表现出来。此时程序也将会报致命错误。属性不可访问或未定义,值判断对象中的属性不存在时,自动执行该函数。属性值未定义释放对象中的不存在的属性值时,自动执行该函数。 一、PHP面向对象编程基础实践 二、PHP面向对象高级编程实践 知识点:类的继承、方法重写、访问控制、static关键字、final关键字、数据访...

    DrizzleX 评论0 收藏0
  • js面向对象浅谈(一)

    摘要:引言对于面向对象,相信大家一定不陌生。创建对象面向对象第一步是什么答创建对象。构造函数优于工厂模式也是在于它可以通过辨识出一类的对象。 引言 对于面向对象,相信大家一定不陌生。最近看了一些关于es6面向对象的知识,正好通过这篇文章把关于面向对象的东西给串起来分享给大家。 什么是对象 很多人会鄙视我,说你这篇文章是骗骗刚入行的小朋友的吧,什么是对象我还能不知道?骂我的吃瓜群众先冷静一下,...

    lastSeries 评论0 收藏0
  • 浅谈面向对象的javascript几个特性

    摘要:中的和是一门很灵活的语言,尤其是。即然是面向对象的编程语言,那也是不可或缺的。在中,永远指向的是他的调用者。定义是存在于实例化后对象的一个属性,并且指向原对象的属性。我们在扩展的时候,同时父类也会有对应的方法,这很显然是一个很严重的问题。 javascript中的this和new javascript是一门很灵活的语言,尤其是function。他即可以以面向过程的方式来用,比如: f...

    JayChen 评论0 收藏0
  • js面向对象浅谈(二)

    摘要:我们通过这个构造函数为原型对象添加其他方法和属性。这个属性存在与实例与构造函数的原型对象上直接,而不存在于实例与构造函数之间。李小花班花张全蛋张全蛋李小花李小花我们在遍历对象的的属性的时候,经常需要判断属性是否来自于对象的原型还是属性。 引言 上面说了创建对象有字面量方式和工厂模式还有构造函数模式,结果发现他们都各自有缺点,所以下面再给大家介绍几种创建对象的方式,争取能找到一种无痛的模...

    Yuanf 评论0 收藏0

发表评论

0条评论

awkj

|高级讲师

TA的文章

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