理解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. win8.1 pro-64位下安装配置MinGW—64位

    1.下载MinGW-w64位:http://mingw-w64.org/doku.php 点击Downloads 说明:这边使用的是在线安装方式: 在网站里可以看到他安装后的文件夹: 2.安装 运行m ...

  2. 微信小程序--分享界面自定义图片

    一般小程序页面都会大于等于1页,每个页面右上角都会有分享功能,建议把以下方法封装到app.js文件,在页面直接调用该方法,避免重复代码,提高性能.(代码用到ES6语法,若不支持,请自行还原js) // ...

  3. C# 如何在Linux操作系统下读取文件

    发布在Window环境上的微服务需要部署在Linux环境上,本以为没有什么问题,结果因为一处读取文件路径的原因报错了,在此记录一下两个问题:1.C#如何判断当前运行环境是什么操作系统:2.C#读取文件 ...

  4. LeetCode 544----Output Contest Matches

    During the NBA playoffs, we always arrange the rather strong team to play with the rather weak team, ...

  5. 报表在IBM AIX系统下resin部署

     报表是用java开发的,具有良好的跨平台性.不仅可以应用在windows.linux.操作系统,还可以应用在AIX等等的unix操作系统.在各种操作系统上部署过程有一些差别.下面说一下在AIX操 ...

  6. 团队项目——软件需求分析(NABCD)

    一.团队项目简介 团队名称:SmartCoder 项目名称:<一起> 二.针对 " 地图可视化查看发布的内容 " 这一特点进行 NABCD 分析 N(Need需求) 往 ...

  7. linux下yum安装指定的mysql版本

    因为直接使用yum安装的mysql会是默认版本5.1的版本  但是有的同学不满足又想要其他版本的怎么办呢? 曾时候我来提供一种方案(仅供参考): 我们可以使用rpm包来进行指定mysql版本的安装, ...

  8. ajax Post数据,并得到返回结果,密码加密(Select,checkbox)

    使用ajax Post数据到后台Server,并从后台返回数据给前端WEB: urls.py: from django.conf.urls import url from aptest import ...

  9. 魅力python------if - else 语句

    引入:if-else的作用,满足一个条件做什么,否则做什么. if-else语句语法结构 if 判断条件: 要执行的代码 else: 要执行的代码 判断条件:一般为关系表达式或bool类型的值 执行过 ...

  10. Ubuntu通过Pyenv管理python版本

    网上安装使用Pyenv的教程很多,但是实测有很多教程有坑,经过多家比较发现下面的教程可用,内容全面,与大家分享. 首先安装pyenv全家桶 curl -L https://raw.githubuser ...