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. 在centos7下安装python3

    环境搭建 准备工具: centos7:http://mirror.bit.edu.cn/centos/7/isos/x86_64/CentOS-7-x86_64-DVD-1611.iso virtus ...

  2. python requests 模拟登陆网站,抓取数据

    抓取页面数据的时候,有时候我们需要登陆才可以获取页面资源,那么我们需要登陆以后才可以跳转到对应的资源页面,那么我们需要通过模拟登陆,登陆成功以后再次去抓取对应的数据. 首先我们需要通过手动方式来登陆一 ...

  3. Unity使用Mono.Xml代替System.Xml 测试

    测试环境 操作系统:Windows8.1 开发工具:Unity5.5.2 1.新建一个测试项目,观测引用System.Xml与Mono.Xml解析文件正确性,与打包后APK体积大小. 2.Mono.X ...

  4. 写给Android App开发人员看的Android底层知识(2)

    (五)AMS 如果站在四大组件的角度来看,AMS就是Binder中的Server. AMS全称是ActivityManagerService,看字面意思是管理Activity的,但其实四大组件都归它管 ...

  5. Java基础知识二次学习-- 第一章 java基础

    基础知识有时候感觉时间长似乎有点生疏,正好这几天有时间有机会,就决定重新做一轮二次学习,挑重避轻 回过头来重新整理基础知识,能收获到之前不少遗漏的,所以这一次就称作查漏补缺吧!废话不多说,开始! 第一 ...

  6. 《算法4》1.5 - Union-Find 算法解决动态连通性问题,Python实现

    Union-Find 算法(中文称并查集算法)是解决动态连通性(Dynamic Conectivity)问题的一种算法,作者以此为实例,讲述了如何分析和改进算法,本节涉及三个算法实现,分别是Quick ...

  7. C#基础篇--面向对象(类与对象)

    1.类是什么?  类就相当于模板,就是把同一类的事物的共同特征进行的抽象. 类的创建和说明: 类是先根据一些具体的对象(实体的东西)来抽象出来的共同的特性,然后用代码来表示. 在类中,用数据表示事物的 ...

  8. java基础之位运算

    java中常见的位运算符:&(逻辑与) |(逻辑或) ~(取反) ^(逻辑异或) >>(右移) <<(左移) >>>(无符号右移) &(逻辑与 ...

  9. webpack 初识

    Webpack介绍 webpack 官网 http://webpack.github.io/docs/ webpack 中文地址:https://doc.webpack-china.org/ webp ...

  10. CI Weekly #20 | 从持续集成的角度看 “云” 的价值

    很多移动开发工程师对 fastlane 耳熟能详,最近 flow.ci 的 iOS 工作流「编译」这步已采用 fastlane gym 工具(iOS 应用打包签名自动化),进一步优化了构建打包速度.快 ...