上一篇随笔讲了封装,这一篇我们说说继承,还是那上一篇猫和狗说事儿

  1. function Dog(name,s){
  2. this.name=name;
  3. this.sex=s;
  4. }
  5. Dog.prototype.type="犬科";
  6. Dog.prototype.spack==function(){
  7. alert("汪汪。。。");
  8. }
  9. function Cat(name,s){
  10. this.name=name;
  11. this.sex=s;
  12. }
  13. Cat.prototype.type="猫科";
  14. Cat.prototype.spack=function(){
  15. alert("喵喵。。。");
  16. }

当然猫和狗都是动物,那他们就有动物的属性,比如需要吃东西,需要呼吸,喝水等等。

现在我们封装一个动物对象:

  1. function Animal(){
  2. this.eat="true";
  3. this.breath="true";
        this.name="动物";
  4. }
  5. Animal.prototype.drink=function(){
      alert("喝水");
    };

现在我们需要让猫的对象继承于动物对象的一些属性呢,我们只需要将父对象的属性绑定到子对象上就能让子对象享受父对象的属性和方法,代码如下:

  1. function Dog(name,s){
  2. Animal.apply(this, arguments);
  3. this.name=name;
  4. this.sex=s;
  5. }
  6. function Cat(name,s){
  7. Animal.apply(this, arguments);
  8. this.name=name;
  9. this.sex=s;
  10. }

当然这种方法也是最简单的,还有别的方法:我们可以用prototype来实现,代码如下

  1. function Dog(name,s){
  2. this.name=name;
  3. this.sex=s;
  4. }
  5. Dog.prototype = new Animal();
    Dog.prototype.constructor = Dog;
  6. Dog.prototype.type="犬科";
  7. Dog.prototype.spack==function(){
  8. alert("汪汪。。。");
  9. }

这样就让猫和狗都继承了动物的属性和方法了,让我们仔细剖析一下这种方式,在将new Animal()赋给Cat.prototype后,

  1. function Cat(name,s){
  2. this.name=name;
  3. this.sex=s;
  4. }
  5. Cat.prototype = new Animal();
  6. console.log(Cat.prototype);
  7. Cat.prototype.type="猫科";
  8. Cat.prototype.spack=function(){
  9. alert("喵喵。。。");
  10. }

控制台输出

  1. Animal {
  2. breath:"true"
  3. eat:"true"
  4. spack:function ()
  5. type:"猫科"
  6. __proto__:Object
  7. }

打开—proto—,我们看到:

  1. __proto__:Object
  2. drink:function ()
  3. constructor:function Animal()
  4. arguments:null
  5. caller:null
  6. length:
  7. name:"Animal"
  8. prototype:Object
  9. __proto__:function ()
  10. [[FunctionLocation]]:test1.html:
  11. [[Scopes]]:Scopes[]
  12. __proto__:Objec

我们在代码里输出一下:

  1. alert(cat1.constructor == Animal); // true

我们很明显发现constructor指向的是Animal(),在程序中它本应该指向Cat();当我们加入Cat.prototype.constructor = Cat,打开constructor再看时发现

  1. constructor:function Cat(name,s)

有人会说我没家这句话难道不行吗,我没加上述代码程序照样继承了父对象的属性和方法,当然在这种小案例中有可能会行,但是在大项目中这样写代码会在造成继承紊乱,造成不可预知的错误,所以我么需要手动调整Cat.prototype.constructor的值,所以我们在程序中如果给prototype赋值,那么下一步必须是将对象.prototype.constructor的值重新指回到原对构造函数。

当然我们也可以让子构造函数直接继承父构造函数的prototype,代码如下:

  1. function Cat(name,s){
  2. this.name=name;
  3. this.sex=s;
  4. }
  5. Cat.prototype = Animal.prototype;
  6. console.log(Cat.prototype);
  7. Cat.prototype.type="猫科";
  8. Cat.prototype.spack=function(){
  9. alert("喵喵。。。");
  10. }

这种方法好处是高效,不需要重新在新建一个对象,当然缺点也很明显,此刻Animate.prototype和Cat.prototype指向同意数据源,不加Cat.prototype.constructor = Cat时Cat.prototype输出Animal(),加了之后Cat.prototype输出Cat(),貌似对了,可是Animal.prototype此刻居然也输出Cat(),原因是此刻Animate.prototype和Cat.prototype指向同意数据源,当Cat.prototype做出修改时事实上该的是它俩的数据源,所以,这种方法不可取。

当然我们还可以通过中间量的思路解决这个问题,代码如下:

  1. function Bridge(){
  2. }
  3. bridge.prototype=Animal.prototype;
  4.  
  5. Cat.prototype=new Bridge();
  6. Cat.prototype.constructor = Cat;

此刻Bridgr没有添加新的方法和属性,所以它几乎不占内存,而同时我们对prototype进行修改也不会影响其父级对象的prototype

我们将上述代码封装成一个函数,以备使用:

  1. function brideg(p,s){
  2. var F=function(){};
  3. F.prototype=p.prototype;
  4. s.prototype = new F();
  5. s.pprototype.constructor= s;
  6. s.uber= p.prototype;
  7. }

此处uper为子对象添加一个属性,这个属性直接指向父对象的prototype,这等于在子对象上打开一条通道,可以直接调用父对象的方法。

  1. extend(Cat,Animal);
  2. var cat1 = new Cat("咪咪","雄");
  3. alert(cat1.name); // 动物

还有一种继承思路,就是将父对象的所有属性全部拷贝给子属性,那么就相当于子对象继承于父对象了

代码如下

  1. function extend(p,s){
  2. var p1=p.prototype;
  3. var s1=s.prototype;
  4. for(var i in p1){
  5. s1[i]=p1[i];
  6. }
  7. s1.uper=p1;
  8. }

调用如下:

  1. extend2(,Animal, Cat);
  2. var cat1 = new Cat("咪咪","雄");
  3. alert(cat1.name); // 动物

--------------------------------------------------------我是分割线-------------------------------------------------------------

本文参考阮大神文章,地址:

  1. http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance.html

js面向对象(二)——继承的更多相关文章

  1. 捋一捋js面向对象的继承问题

    说到面向对象这个破玩意,曾经一度我都处于很懵逼的状态,那么面向对象究竟是什么呢?其实说白了,所谓面向对象,就是基于类这个概念,来实现封装.继承和多态的一种编程思想罢了.今天我们就来说一下这其中继承的问 ...

  2. js面向对象之继承那点事儿根本就不是事

    继承 说道这个继承,了解object-oriented的朋友都知道,大多oo语言都有两种,一种是接口继承(只继承方法签名):一种是实现继承(继承实际的方法) 奈何js中没有签名,因而只有实现继承,而且 ...

  3. JS面向对象组件 -- 继承的其他方式(类式继承、原型继承)

    继承的其他形式: •类式继承:利用构造函数(类)继承的方式 •原型继承:借助原型来实现对象继承对象   类 : JS是没有类的概念的 , 把JS中的构造函数看做的类 要做属性和方法继承的时候,要分开继 ...

  4. JS——面向对象、继承

    创建对象的方式: 1)单体 <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...

  5. JS 面向对象之继承 -- 原型链

    ECMAScript只支持实现继承,其实现继承主要是靠原型链来实现. 原型链的基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法. 简单回顾下构造函数.原型和实例的关系: 每个构造函数都有 ...

  6. js高程(二)-----继承

    首先来讨论一下原型链,上代码 function SuperType(){ this.property = true; } SuperType.prototype.getSuperValue = fun ...

  7. js面向对象之继承-原型继承

    //animal 父类 超类 var Animal = function(name) { this.name = name; this.sayhello = function() { alert(&q ...

  8. JS 面向对象之继承---多种组合继承

    1. 组合继承:又叫伪经典继承,是指将原型链和借用构造函数技术组合在一块的一种继承方式. 下面来看一个例子: function SuperType(name) { this.name = name; ...

  9. Js面向对象构造函数继承

    构造函数继承 <!-- 创建构造函数 --> function Animal(){ this.species= '动物'; } function Dog(name,color){ this ...

  10. JS面向对象笔记二

    菜单导航,<JS面向对象笔记一>,  参考书籍:阮一峰之<JavaScript标准参考教程> 一.构造函数和new命令 二.this关键字 三.构造函数和new命令 四.构造函 ...

随机推荐

  1. MP3 Lame 转换 参数 设置(转)

    我们在对音频格式的转换中,打交道最多的就是MP3了.如果你能彻底玩转MP3,那么对你的音频创作和对其他音频格式的掌握会有很大的帮助.下面我们给大家介绍MP3制作软件:LAME 要制作出高音质的MP3靠 ...

  2. [GO]通过结构体生成json

    package main import ( "encoding/json" "fmt" ) type IT struct { //一定要注意这里的成员变量的名字 ...

  3. oracle中的表空间(tablespace)、方案(schema)、段(segment)、区(extent)、块(block)

    数据文件和日志文件是数据库中最重要的文件.它们是数据存储的地方.每个数据库至少有一个与之相关的数据文件,通常情况下不只一个,有很多.数据在数据文件中是如何组织的?要了解这些内容我们首先必须理解什么是表 ...

  4. Arch Linux 使用markdown

    Arch Linux 使用markdown pandoc 文档格式转换 pygments 代码高亮 markdown-mode.el 配置emacs pandoc 号称文件格式转换的瑞士军刀,这里主要 ...

  5. Alpha阶段项目复审(菜就完事了队)

    Alpha阶段项目复审 小组 优点 缺点 名次 天冷记得穿秋裤队 实现的功能完整,可以离线下载 下载不稳定,大文件无法下载 1 中午吃啥队 使用方便,操作简单 界面适应不够好 2 只会嘤嘤嘤队 游戏和 ...

  6. Backup--清理MSDB中的备份记录

    每次数据库备份或日志备份,都会向msdb中多多张表插入数据,如果备份比较频繁的话,需要定期清理. 使用sp_delete_backuphistory来清理以下表中数据: backupfile back ...

  7. .netcore 与 Docker

    CentOS下Docker与.netcore(一) 之 安装 CentOS下Docker与.netcore(二) 之 Dockerfile CentOS下Docker与.netcore(三)之 三剑客 ...

  8. c# 读取网卡Mac

    ///<summary> /// 通过NetworkInterface读取网卡Mac ///</summary> ///<returns></returns& ...

  9. MongoDB基础知识记录

    MongoDB基础知识记录 一.概念: 讲mongdb就必须提一下nosql,因为mongdb是nosql的代表作: NoSQL(Not Only SQL ),意即“不仅仅是SQL” ,指的是非关系型 ...

  10. Django-05模型层之多表操作2

    7.3 多表操作 一.创建模型 实例:我们来假定下面这些概念,字段和关系作者模型:一个作者有姓名和年龄.作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之 ...