理解JavaScript继承(二)

5.寄生式继承

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

这个实例基于person返回了一个新对象anotherPerson。新对象不仅具有person的所有属性和方法,而且还有自己的sayHi()方法。

缺点:和构造函数一样,不能做到函数复用而降低效率。

6.寄生组合式继承

前面介绍说组合继承是JavaScript最常用的继承模式;实际上,它也存在一些问题,组合继承的最大问题是无论什么情况下,都会调用两次超类型构造函数:一次是在创建子类型原型的时候,另一次是在子类型构造函数内部。

组合式继承实例

function SuperType(name){
this.name = name;
this.colors = ["red", "blue", "green"];
} SuperType.prototype.sayName = function(){
alert(this.name);
}; function SubType(name, age){
SuperType.call(this, name);//第二次调用SuperType() this.age = age;
} SubType.prototype = new SuperType();//第一次调用SuperType() SubType.prototype.sayAge = function(){
alert(this.age);
};

在第一次调用SuperType()构造函数时,SubType.prototype会得到两个属性:name和colors;他们都是SuperType的实例属性,只不过现在位于SubType的原型中。当调用SubType构造函数时,又会调用一次SuperType构造函数,这一次又在新对象上创建了实例属性name和colors,于是,这两个属性就屏蔽了原型中的两个同名属性。

上面一共有两组name和colors属性:一组在实例上,一组在SubType原型中。这就是调用两次SuperType的结果。

为了解决这种情况,于是就出现了下面的——寄生组合式继承方法。

所谓寄生组合式继承,即通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。其背后的基本思路是:不必为了指定子类型的原型而调用超类型的构造函数,我们所需要的无非就是超类型原型的一个副本而已。(之所以是超类型的副本,而不是直接是超类型,如果直接是超类型的话。当子类型为原型添加方法时,也会影响到超类型的)

寄生组合式继承

function object(o){
function F(){}
F.prototype = o;
return new F();
} function inheritPrototype(subType, superType){
var prototype = object(superType.prototype); //创建对象
prototype.constructor = subType; //增强对象
subType.prototype = prototype; //指定对象
} function SuperType(name){
this.name = name;
this.colors = ["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);
}; 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

上面实例只在SuperType.call(this, name);这调用了一次构造函数,并且因此避免了在prototype上面创建不必要的,多余的属性。

注:YUI的extend()就是采用这种寄生组合式继承

理解JavaScript继承(二)的更多相关文章

  1. 理解JavaScript继承

    原文:理解JavaScript继承 对于JavaScript的继承和原型链,虽然之前自己看了书也听了session,但还是一直觉得云里雾里,不禁感叹JavaScript真是一门神奇的语言.这次经过Sp ...

  2. 理解JavaScript继承(三)

    理解JavaScript继承(三) 通过把父对象的属性,全部拷贝给子对象,也能实现继承. 7.浅拷贝 function extendCopy(p) { var o = {}; for (var pro ...

  3. 理解JavaScript继承(一)

    理解JavaScript继承(一) 我们都知道,面向对象的编程语言非常强大,之所以强大,就是其支持继承.在JavaScript中,也支持继承,而且有多种方法实现继承,比如原型链继承,借用构造函数继承, ...

  4. 深入理解 JavaScript(二)

    立即调用的函数表达式 前言 大家学 JavaScript 的时候,经常遇到自执行匿名函数的代码,今天我们主要就来想想说一下自执行. 在详细了解这个之前,我们来谈了解一下"自执行"这 ...

  5. javascript继承(二)—创建对象的三种模式

    一.工厂模式 function createPerson(name,age){ var o = {}; o.name = name; o.age = age; o.sayHi = function() ...

  6. 彻底理解Javascript原型继承

    彻底理解Javascript原型继承 之前写过一篇Javascript继承主题的文章,这篇文章作为一篇读书笔记,分析的不够深入. 本文试图进一步思考,争取彻底理解Javascript继承原理 实例成员 ...

  7. 理解Javascript的动态语言特性

    原文:理解Javascript的动态语言特性 理解Javascript的动态语言特性 Javascript是一种解释性语言,而并非编译性,它不能编译成二进制文件. 理解动态执行与闭包的概念 动态执行: ...

  8. 深入理解javascript原型和闭包(6)——继承

    为何用“继承”为标题,而不用“原型链”? 原型链如果解释清楚了很容易理解,不会与常用的java/C#产生混淆.而“继承”确实常用面向对象语言中最基本的概念,但是java中的继承与javascript中 ...

  9. 理解JavaScript中的原型继承(2)

    两年前在我学习JavaScript的时候我就写过两篇关于原型继承的博客: 理解JavaScript中原型继承 JavaScript中的原型继承 这两篇博客讲的都是原型的使用,其中一篇还有我学习时的错误 ...

随机推荐

  1. CodeForces765B

    B. Code obfuscation time limit per test:2 seconds memory limit per test:512 megabytes input:standard ...

  2. PHP通用分页类page.php[仿google分页]

    <?php /** ** 通用php分页类.(仿Google样式) ** 只需提供记录总数与每页显示数两个参数.(已附详细使用说明..) ** 无需指定URL,链接由程序生成.方便用于检索结果分 ...

  3. flutter开发中常用的dart插件

    flutter插件官网地址:https://pub.dartlang.org/packages/ 1. image_picker 一个可以从图库选择图片,并可以用相机拍摄新照片的flutter插件 2 ...

  4. python 字符串的方法和注释

    capitalize() 把字符串的第一个字符改为大写 casefold() 把整个字符串的所有字符改为小写 center(width) 将字符串居中,并使用空格填充至长度 width 的新字符串 c ...

  5. MQTT介绍(1)简单介绍

    MQTT目录: MQTT简单介绍 window安装MQTT服务器和client java模拟MQTT的发布,订阅 MQTT: MQTT(Message Queuing Telemetry Transp ...

  6. ORACLE数据库AWR工具学习

    AWR(Automatic Workload Repository)即工作负载信息库,主要用于收集数据库运行状态的资料库,通过AWR报告可以分析ORACLE数据库的性能,从而给出优化策略. 图一:此图 ...

  7. Oracle EBS 启用关于此页

    FND:诊断英文为FND: Diagnostics,用于设置是否显示“关于此页”个性化自助定义英文为Personalize Self-Service Defn,用户设置在登录后,OAF页面是否显示“个 ...

  8. [控件] 心形加载的view

    心形加载的view 效果: 素材图片: 源码: StarView.h 与 StarView.m // // StarView.h // Star // // Created by XianMingYo ...

  9. 用以替换系统NSLog的YouXianMingLog

    用以替换系统NSLog的YouXianMingLog 这是本人自己使用并改良的用以替换系统NSLog的类,非常好用,以下是使用示例,现在开源出来并提供源码,好用的话顶一下吧^_^ 效果: YouXia ...

  10. cxfreeze打包python程序的方法说明(生成安装包,实现桌面快捷方式、删除快捷方式)

    一.cxfreeze基础 1.cxfreeze功能 python代码文件转exe方法有三种,分别是cx_freeze,py2exe,PyInstaller,这三种方式各有千秋,本人只用过py2exe和 ...