资讯专栏INFORMATION COLUMN

JS学习笔记(第6章)(实现继承的几种方式)

hiyayiji / 652人阅读

摘要:使用最多的继承模式是组合继承,这种模式使用原型链继承共享的属性和方法,而借用构造函数继承实例属性。原型式继承,可以在不必预先定义构造函数的情况下实现继承,其本质是执行给定对象的浅复制。

1、原型链实现继承
function SuperType() {
    this.property = true;
}
SuperType.prototype.getSuperValue = function() {
    return this.property;
};

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

//继承了SuperType
SubType.prototype = new SuperType();

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

var instance = new SubType();
alert(instance.getSuperValue());   //true
2、借用构造函数

原型链的问题是对象实例共享所有继承的属性和方法,因此不适宜多带带使用。解决这个问题的技术是借用构造函数,即在子类型构造函数的内部调用超类型构造函数。这样就可以做到每个实例都具有自己的属性,同时还能保证只使用构造函数模式来定义类型。

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

function SubType(){
    //继承了SuperType,
    SuperType.call(this);//在子类型构造函数的内部调用超类型构造函数
}

var instance1 = new SubType();
instance1.colors.push("black");
alert(instance1.colors);   //"red,blue,green,black"

var instance2 = new SuperType();
alert(instance2.colors);   //"red,blue,green"
3、组合继承

思想:在子类型构造函数的内部调用超类型构造函数。使用最多的继承模式是组合继承,这种模式使用原型链继承共享的属性和方法,而借用构造函数继承实例属性。

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

SuperType.prototype.sayName = function() {
    alert(this.name);
};
function SubType(name ,age) {
    //继承属性
    SuperType.call(this,name);//在子类型构造函数的内部调用超类型构造函数
    this.age = age;
}
//继承方法
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;  //指向构造函数
SubType.prototype.sayAge = function() {
    alert(this.age);
};
var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
alert(instance1.colors);   //"red,blue,green,black"
instance1.sayName();  //"Nicholas"
instance1.sayAge();  //29

var instance2 = new SubType("Greg" ,27);
alert(instance2.colors);  //"red,blue,green"
instance2.sayName();  //"Greg"
instance2.sayAge();  //27
4、原型式继承

(1)借助原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型
(2)在object()函数内部,先创建了一个临时性的构造函数,然后将传入的对象作为这个构造函数的原型,最后返回这个临时类型的一个新实例。
(3)原型式继承,可以在不必预先定义构造函数的情况下实现继承,其本质是执行给定对象的浅复制。而复制的副本还可以得到进一步的改造。

var person = {
    name : "Nicholas",
    friends : ["Shelby", "Court", "Van"]
};

var anotherPerson = object(perosn);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");

var yetAbotherPerson = object(perosn);
yetAbotherPerson.name = "Linda";
yetAbotherPerson.firends.push("Barbie");

alert(person.friends);  //"Shelby, Court, Van, Greg, Linda"
5、寄生式继承

与原型式继承非常相似,也是基于某个对象或某些信息创建一个对象,然后增强对象,最后返回对象。为了解决组合继承模式由于多次调用超类型函数而导致的低效率问题,可以将这个模式与组合继承一起使用。

function creatAnother(original) {
    var clone = object(original);   //通过调用函数创建一个新对象
    clone.sayHi = function() {      //以某种方式来增强这个对象
        alert("hi");
    };
    return clone;  //返回这个对象
}
var person = {
   name : "Nicholas",
   friends : ["Shelby", "Court", "Van"]
};

var anotherPerson = creatAnother(person);
anotherPerson.sayHi();  //"hi"
6、寄生组合式继承

(1)集寄生式继承与组合继承的优点于一身,是实现基于类型继承的最有效的方式。可以解决组合继承调用两次构造函数导致子类最终会包含超类对象的全部实例属性的问题。
(2)寄生式组合继承,就是通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。其思想是:不必为了指定子类型的原型而调用超类型的构造函数,我们所需的无非就是超类型原型的一个副本而已。本质上就是,使用寄生式继承来继承超类型的原型,然再将结果指定给子类型的原型。其基本模式如下:

function inheritPrototype(SubType,superType) {
    var prototype = object(superType.prototype);   //创建对象
    prototype.constructor = subType;               //增强对象
    subType.prototype = prototype;                 //指定对象
}

这个函数接收两个参数:子类型构造函数和超类型构造函数。
第一步是创建超类型原型的一个副本;
第二步是为创建的副本添加constructor属性,从而弥补因重写原型而失去的默认的constructor属性;
第三步将新创建的对象(即副本)赋值给子类型的原型。

function inheritPrototype(SubType,superType) {
    var prototype = object(superType.prototype);   //创建对象
    prototype.constructor = subType;               //增强对象
    subType.prototype = prototype;                 //指定对象
}

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

SuperType.prototype.sayName = function() {
    alert(this.name);
};
function SubType(name ,age) {
    //继承属性
    SuperType.call(this.name);      
    this.age = age;
}

inheritPrototype(SubType, SuperType);

SubType.prototype.sayAge = function() {
    alert(this.age);
};

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

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

相关文章

  • 基本方法笔记 - 收藏集 - 掘金

    摘要:探讨判断横竖屏的最佳实现前端掘金在移动端,判断横竖屏的场景并不少见,比如根据横竖屏以不同的样式来适配,抑或是提醒用户切换为竖屏以保持良好的用户体验。 探讨判断横竖屏的最佳实现 - 前端 - 掘金在移动端,判断横竖屏的场景并不少见,比如根据横竖屏以不同的样式来适配,抑或是提醒用户切换为竖屏以保持良好的用户体验。 判断横竖屏的实现方法多种多样,本文就此来探讨下目前有哪些实现方法以及其中的优...

    maochunguang 评论0 收藏0
  • JS学习笔记24)(最佳实践)

    摘要:大多数情况下,可以是同局部变量完成相同的事情而不引入新的作用域。选择正确的方法避免不必要的属性查找一旦多次用到属性对象,应该将其存储在局部变量中。尽可能多的使用局部变量将属性查找替换为值查找。 1、可维护性 1.1 可维护代码特征 1. 可理解性 2. 直观性 3. 可适应性 4. 可扩展性 5. 可调试性 1.2 代码约定 1、可读性(代码缩进和代码注释) 2、变量和函数命名 变量...

    cnTomato 评论0 收藏0
  • JS学习笔记6)(面向对象之继承——JS继承的六大方式

    摘要:除此之外,在超类型的原型中定义的方法,对子类型而言也是不可兼得,结果所有类型都只能用构造函数模式。创建对象增强对象指定对象继承属性这个例子的高效率体现在它只调用了一次构造函数。 1、原型链 原型链的基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。构造函数、原型和实例的关系:每个构造函数都有一个原型对象;原型对象都包含着一个指向构造函数的指针;实例都包含一个指向原型对象的...

    lscho 评论0 收藏0
  • 读《javaScript高级程序设计-6》之封装类

    摘要:创建构造函数后,其原型对象默认只会取得属性至于其他的方法都是从继承来的。上图展示了构造函数的原型对象和现有的两个实例之间的关系。所有原生的引用类型都在其构造函数的原型上定义了方法。 第6章我一共写了3篇总结,下面是相关链接:读《javaScript高级程序设计-第6章》之理解对象读《javaScript高级程序设计-第6章》之继承 工厂模式 所谓的工厂模式就是,把创建具体对象的过程抽象...

    seal_de 评论0 收藏0
  • 写技术博客那点事

    摘要:从现在开始,养成写技术博客的习惯,或许可以在你的职业生涯发挥着不可忽略的作用。如果想了解更多优秀的前端资料,建议收藏下前端英文网站汇总这个网站,收录了国外一些优质的博客及其视频资料。 前言 写文章是一个短期收益少,长期收益很大的一件事情,人们总是高估短期收益,低估长期收益。往往是很多人坚持不下来,特别是写文章的初期,刚写完文章没有人阅读会有一种挫败感,影响了后期创作。 从某种意义上说,...

    ddongjian0000 评论0 收藏0

发表评论

0条评论

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