Js继承

JavaScript并不是真正面向对象的语言,是基于对象的,没有类的概念。
要想实现继承,可以用js的原型prototype机制或者用apply和call方法去实现

/**
    声明一个基础父类
*/
function Hero(name,skill){
    this.name = name?name:'';
    this.skill = skill?skill:'';
}
Hero.prototype.sayHello = function(){
    console.log(this.name + ";" + this.skill);
}

//类静态常量
Hero.type = "I'm Hero";
//类静态方法
Hero.doSomething = function(){
    console.log('doSomething');
}

子类的定义

1. 使用prototype继承

优缺点

  • 该方法能继承父类的属性,方法
  • 若父类构造器有参数,无法向父构造器传参数·
  • 若父类原型进行了修改会影响到子类实例
  • 构造函数的静态常量不能继承到

实现方法:

  • 把父类的实例付给子类的原型 Children.prototype = new Parent();
  • 要添加 Children.prototype.constructor = Children语句 使 构造函数 等于 原型的constructor
function CNHero(era){
    this.era = era;
}

CNHero.prototype = new Hero();
//使构造函数 等于 原型的constructor
CNHero.prototype.constructor = CNHero;

//类静态常量/方法不会继承 需要自己声明
CNHero.type = "I'm CNHero";

var cnHero = new CNHero('三国时代');

//以下属性均是来自父类的(__poro__)
cnHero.name;// =>''   继承了父类的属性
cnHero.skill;// =>''  

//给该属性设值,该属性会在实例下面创建,不会改变__poro__下的值
cnHero.name = 'CNHero:诸葛亮';
cnHero.skill = '东风计';

cnHero.sayHello();//=>诸葛亮;东风计;I'm CNHero

//若父类原型进行了修改会影响到子类实例 与原来父类的原型链相互影响 CNHero - > new Hero - > Hero.prototype
cnHero.change;//=>undefined
Hero.prototype.change = 'change';
cnHero.change;//=>change

2. 使用apply,call继承(构造器继承)

  • 在构造函数中调用父类的构造函数(创建子类就能够传入需要的属性)
  • 该方法能继承 父类的属性(即父类构造器里面的方法,属性)
  • 不能继承父类的原型方法,原型属性
  • 相当于把父类的属性方法拷贝到子类(消耗会变大)
  • 构造函数的静态常量不能继承到
function CNHero(name,skill,era){
    Hero.call(this,name,skill); // <=>Hero.apply(this,[]);
    this.era = era;
}
//类静态常量/方法不会继承 需要自己声明
CNHero.type = "I'm CNHero";
var hero = new CNHero('诸葛亮','72计','三国时代');
console.log(hero.type);     //=>I'm Hero

try{
    hero.sayHello();    //=>继承不了父类原型的方法
}catch(e){
    console.log(e);     //=> hero.sayHello is not a function
}
    

3.prototype,call/apply组合使用 (组合继承)

  • 该方法能继承 父类的属性,方法
  • 可调用父类的构造函数
  • 会初始化父类两次 ,出现属性重复(子类以及原型有重复属性)
  • 构造函数的静态常量不能继承到
//1.使用call方法调用父类构造函数
function CNHero(name,skill,era){
    Hero.call(this,name,skill); // <=>Hero.apply(this,[]);
    this.era = era;
}

//改变prototype的指向
CNHero.prototype = new Hero();
//使 构造函数 等于 原型的constructor
CNHero.prototype.constructor = CNHero;
//类静态常量/方法不会继承 需要自己声明
CNHero.type = "I'm CNHero";
var hero = new CNHero('诸葛亮','东风计');

hero.sayHello();        //=>诸葛亮;东风计;I'm CNHero

4. 寄生继承

  • 组合继承的改进方法,可以避免属性重复的问题
  • 构造函数的静态常量不能继承到
function CNHero(name,skill,era){
    Hero.call(this,name,skill); // <=>Hero.apply(this,[name,skill]);
    this.era = era;
}

//闭包,不影响外面的执行
(function(){
    // 创建一个间接类 并 将父类的原型赋值给间接类 这样能够避免将父类的属性添加到子类
    var Super = function(){};
    Super.prototype = Hero.prototype;
    //将实例作为子类的原型
    CNHero.prototype = new Super();
}());

//使 构造函数 等于 原型的constructor
CNHero.prototype.constructor = CNHero;
//类静态常量/方法不会继承 需要自己声明
CNHero.type = "I'm CNHero";

var hero = new CNHero('诸葛亮','东风计','三国时代');

hero.sayHello();        //=>诸葛亮;东风计;I'm CNHero

Javascript 类继承的更多相关文章

  1. JavaScript类继承, 用什么方法好

    JavaScript类继承, 用什么方法好 一个实例: 基类Car: function Car(color, year) { this.name = "car"; this.col ...

  2. Javascript类继承-机制-代码Demo【原创】

    最近看到<Javascript设计模式>,对js模拟的”继承方式“有了更深一步的了解,虽然之前也总是用到prototype.new ,但只是知其然不知所以然,现在将类继承的方法整理如下,暂 ...

  3. javascript类继承的一些实验

    其实一开始编js没怎么用过对象,一般都用func,func,func···但是用多了,感觉代码一点都不美观,还要这里包一个函数,那里包一个函数,或者一直都是函数调用,不好看,而且一些重用的都要重写的话 ...

  4. JavaScript类继承

    和其他功能一样,ECMAScript 实现继承的方式不止一种.这是因为 JavaScript 中的继承机制并不是明确规定的,而是通过模仿实现的.这意味着所有的继承细节并非完全由解释程序处理.作为开发者 ...

  5. javascript类继承系列五(其他方式继承)

    除了前面学习的三种继承外,还有另外三种:原型继承寄生继承,寄生组合继承都是以: function object(o) { function F() { } F.prototype = o; retur ...

  6. javascript类继承系列二(原型链)

    原型链是采用最主要的继承方式,原理:每一个类(构造器,js中的function)都有一个原型属性(prototype)指向一个原型对象,原型对象有一个构造器(constructor),它又指回到fun ...

  7. javascript类继承系列四(组合继承)

    原理: 结合了原型链和对象伪装各自优点的方式,基本思路是:使用原型链继承原型上的属性和方法,使用对象伪装继承实例属性,通过定义原型方法,允许函数复用,并运行每个实例拥有自己的属性 function B ...

  8. javascript类继承系列三(对象伪装)

    原理:在子类的构造器上调用超类构造器(父类构造器中的this指向子类实例),js提供了apply()和call()函数,可以实现这种调用 function baseClass() { this.col ...

  9. javascript类继承系列一

    js中没有提供类(class,抽象类,接口等高级的抽象),可以用new,但new的function的对象,构造器 但在js中可以通过function来模拟类的一些特性function fun_name ...

随机推荐

  1. jQuery手风琴制作

    jQuery手风琴制作 说起手风琴,想必大家应该都知道吧,简单的来说就是可以来回收缩的这么一个东西,接下来,我就给大家演示一下用jQuery制作一个手风琴菜单! 写jQuery前,我们需要引用一个jQ ...

  2. 关于listener监听器的一些记录

    实现ServletContextListener后,需要实现2个方法,一个是contextInitialized,这个方法会在context被创建的时候执行,这个方法有一个参数为ServletCont ...

  3. Cassandra Issue with Tombstone

    1. Cassandra is quicker than postgre and have lower change to lose data. Cassandra doesn't have fore ...

  4. C语言socket编程——linux环境

    先写一个服务器端的监听程序,功能室从客户端读取字符,接收到后告知客户端“I got your message: ”+收到的消息:server.c #include <stdio.h> #i ...

  5. linux JDK或JRE安装或配置

    1. 使用命令“java –version”如果显示如下内容则jdk已安装成功则无需后续操作. 2. 将解压后的文件“jdk-7u79-linux-x64.rpm ”上传到linux系统目录:/usr ...

  6. 利用formatter原理自动化参数化查询

    前言:对于经常忙于服务端开发的小伙伴来说,与DB层打交道是在正常不过的事了,但是每次页面的查询条件新增往往意味着后端代码参数化同比增长,当然你可以不使用sqlhelper自带的参数化条件查询,可以直接 ...

  7. MySQL1-基础知识点

    目录 零.MySQL安装与配置 一.基本概念 二.基本语法 三.常用指令 四.四种SQL语句       零.MySQL安装与配置 http://www.cnblogs.com/hikarusun/a ...

  8. css中那些容易被我们程序猿所忽略的选择器

    css中那些容易被我们程序猿所忽略的选择器 作为一个程序猿,我们可能会遇到这样的问题,假如:有5个li,要求给第三个li设置背景颜色怎么办?有人会说,用JS啊,循环遍历出第三个不就行了.但是,用JS解 ...

  9. javaCV开发详解之7:让音频转换更加简单,实现通用音频编码格式转换、重采样等音频参数的转换功能(以pcm16le编码的wav转mp3为例)

    javaCV系列文章: javacv开发详解之1:调用本机摄像头视频 javaCV开发详解之2:推流器实现,推本地摄像头视频到流媒体服务器以及摄像头录制视频功能实现(基于javaCV-FFMPEG.j ...

  10. Android应用安全学习笔记前言

    Android是基于Linux kernel的一个自由及开放源代码的操作系统,主要用于移动设备.在2011年第一季度超越了塞班系统跃居了全球第一.本系列作为分享的东西吧.比较基础. 文章也不知道会分为 ...