`
lcyangily
  • 浏览: 21740 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

简单实现JavaScript继承

 
阅读更多

    看John Resig 的JavaScript实现继承的文章,对大神的实现代码拿来跟大家一起读下源码,因为英语太菜就不翻译了,直接根据源码来分析了。原文地址:http://ejohn.org/blog/simple-javascript-inheritance/

 

首先来看本继承所要达到的效果,知道效果来看源码更能容易理解。(先要知其然,然后知其所以然)。

 

var Person = Class.extend({
  init: function(isDancing){
    this.dancing = isDancing;
  },
  dance: function(){
    return this.dancing;
  }
});
var Ninja = Person.extend({
  init: function(){
    this._super( false );
  },
  dance: function(){
    // Call the inherited version of dance()
    return this._super();
  },
  swingSword: function(){
    return true;
  }
});

var p = new Person(true);
p.dance(); // => true

var n = new Ninja();
n.dance(); // => false
n.swingSword(); // => true

 

 继承需要做到以下几点:

1.定义一个简单的结构,有一个初始化方法(生成对象时调用的函数,类似Java的构造方法)

2.子类的生成,必须要继承一个父类。

3.所有类的原型都是派生自Class.(就像Java类最终都派生自Object一样)

4.在子类中提供一种方法能访问到父类中被覆盖的方法。通过this._super().(如:在类Ninja的init方法中调用this._super()就是调用父类Person的init方法)

 

下面来看看代码是怎么实现继承的:

/* Simple JavaScript Inheritance
 * By John Resig http://ejohn.org/
 * MIT Licensed.
 */
// Inspired by base2 and Prototype
(function(){
  var initializing = false, 
      fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
      //fnTest是一正则表达式,匹配函数里是否有调_super方法。
  // The base Class implementation (does nothing)
  this.Class = function(){}; // 定义一个全局变量Class类/函数。
  
  // Create a new Class that inherits from this class
  Class.extend = function(prop) {
    /** 保存当前对象的原型(也就父类的原型),
     *  Class.extend()调用时this是Class,Person.extend调用时this是Person
     *  js里一切都是对象,Class函数也是对象,所以this这里是一个函数。
     */
    var _super = this.prototype;    
    
    // Instantiate a base class (but only create the instance,
    // don't run the init constructor)
    initializing = true;
    /**父类的实例作为子类的原型(典型的原型继承)
     * 但是这里实例化跟普通的生成对象不一样,这里不调用父类的init方法。
     * 类就是一模板,所以子类在以父类对象为原型的时候,不应调用初始化方法,仅仅是生成一个模板
     * 这边就是用initializing变量来标识实例父类是否是赋值给子类的原型。
     * 用闭包来隐藏了initializing 作为全局变量的污染
     */
    var prototype = new this();
    initializing = false;
    
    // Copy the properties over onto the new prototype
    for (var name in prop) {
      // Check if we're overwriting an existing function
      /** 当子类新方法父类中有同名函数,而且子类中调用了父类方法(函数中有_super的调用)
       *  这里使用了代理模式,在调用函数前先将this._super用tmp保存起来(也可能没有_super方法)
       *  在将this._super 赋值为父类中同名函数。调用结束再将原来的this._super还原
       */
      prototype[name] = typeof prop[name] == "function" && 
        typeof _super[name] == "function" && fnTest.test(prop[name]) ?
        (function(name, fn){
          return function() {
            var tmp = this._super;
            
            // Add a new ._super() method that is the same method
            // but on the super-class
            this._super = _super[name];
            
            // The method only need to be bound temporarily, so we
            // remove it when we're done executing
            var ret = fn.apply(this, arguments);        
            this._super = tmp;
            
            return ret;
          };
        })(name, prop[name]) :
        prop[name];
    }
    
    // The dummy class constructor
    function Class() {
      // All construction is actually done in the init method
      /**如果定义了初始化方法init,则调用init初始化
       * 注意:这里的this不是Class或者Person等类/函数对象
       * 而是实例化后的对象var p = new Person() 这里的this 是p
       */
      if ( !initializing && this.init )
        this.init.apply(this, arguments);
    }
    
    // Populate our constructed prototype object
    Class.prototype = prototype; //子类原型复制
    
    // Enforce the constructor to be what we expect
    Class.prototype.constructor = Class; //子类构造函数定义

    // And make this class extendable
    //定义类的继承方法,保证每个新类也都有extend.
    //这里也可写成 Class.extend = this.extend;
    Class.extend = arguments.callee;
    
    return Class;
  };
})();

 看这些代码最重要的一点是时刻要清楚this是哪个对象。

 

好了,上面就是文章的全部了,希望对大家有帮助,有疑问请留言,有什么解释不对和不清楚的地方也望大家指正。

 

分享到:
评论

相关推荐

    JavaScript继承基础讲解(原型链、借用构造函数、混合模式、原型式继承、寄生式继承、寄生组合式继承)

    说好的讲解JavaScript继承,可是迟迟到现在讲解。废话不多说,直接进入正题。  既然你想了解继承,证明你对JavaScript面向对象已经有一定的了解,如还有什么不理解的可以参考《面向对象JS基础讲解,工厂模式、构造...

    浅谈Javascript实现继承的方法

    本文给大家简单介绍了下如何在javascript中实现继承的几种方法,十分的实用,有需要的小伙伴可以参考下。

    JavaScript mixin实现多继承的方法详解

    本文实例讲述了JavaScript mixin实现多继承的方法。分享给大家供大家参考,具体如下: mixin简单通俗的讲就是把一个对象的方法和属性拷贝到另一个对象上,注意这个继承还是有区别的。js是一种只支持单继承的语言,...

    JavaScript使用原型和原型链实现对象继承的方法详解

    主要介绍了JavaScript使用原型和原型链实现对象继承的方法,简单讲述了javascript原型与原型链的原理,并结合实例形式详细分析了javascript中对象继承的常见实现技巧,需要的朋友可以参考下

    详解Javascript继承的实现

    本文从以下四个方面展开话题: ...正因如此,我从没想过下次写继承的时候,我要换一种方式来写,直到今天晚上看了三生石上关于javascript继承系列的文章(出的很早,现在才看,真有点可惜),才发现在js里

    classy.js:一个简单的 Javascript 继承实现

    Classy 是一个 Javascript 继承实现。 这几乎就是你需要知道的一切。 您将获得一种在代码中实现 Javascript 类的简单方法以及一个有用的“包含”方法。 ##例子 ###Building.js Class ( "Building" , { //...

    javascript实现继承的简单实例

    主要介绍了javascript实现继承的简单实例的相关资料,需要的朋友可以参考下

    推荐JavaScript实现继承的最佳方式

    实现JavaScript继承的最简单的方式是call方法(或者apply方法)及原型链方法,但这两种方法都有缺陷,而其混合体就是很好的继承实现方式。下面举例说明: 代码如下: function Animal(age){  this.age = age; } ...

    Javascript简单实现面向对象编程继承实例代码

    主要介绍了Javascript简单实现面向对象编程继承实例代码,简单分析了面向对象程序设计的特征与继承的具体实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下

    JavaScript继承模式粗探

    Javascript原型继承是一个被说烂掉了的话题,但是自己对于这个问题一直没有彻底理解,今天花了点时间又看了一遍《Javascript模式》中关于原型实现继承的几种方法,下面来谈谈JS中比较简单的继承方法,如果大家有不同...

    JavaScript 继承详解(六)

    在本章中,我们将分析Prototypejs中关于JavaScript继承的实现。 Prototypejs是最早的JavaScript类库,可以说是JavaScript类库的鼻祖。 我在几年前接触的第一个JavaScript类库就是这位,因此Prototypejs有着广泛的...

    JavaScript继承与多继承实例分析

    本文实例讲述了JavaScript继承与多继承。分享给大家供大家参考,具体如下: 虽然最新的EC6里边已经有了class的相关功能,但是从普及度上和阅读旧代码需求的方面来看,这点知识也得了解一下。 本文结构: ① 原理及...

    【JavaScript源代码】JavaScript中的几种继承方法示例.docx

    JavaScript中的几种继承方法示例  1.原型链继承  原理: 子类原型指向父类实例对象实现原型共享,即Son.prototype = new Father()。 这里先简单介绍下原型 js中每个对象都有一个__proto__属性,这个属性指向的...

    用JavaScript实现单继承和多继承的简单方法

    JavaScript是一种强大的多泛型编程语言,其融合了面向过程、面向对象和函数式编程于一身,具备强大的表现能力。

    JavaScript类和继承 prototype属性

    我们已经在第一章中使用prototype属性模拟类和继承的实现。 prototype属性本质上还是一个JavaScript对象。 并且每个函数都有一个默认的prototype属性。 如果这个函数被用在创建自定义对象的场景中,我们称这个函数为...

    inheritancejs:一个简单的javascript继承实用程序

    用于实现javascript继承的简单实用程序 安装 npm install inheritancejs 用法 var extend = require ( 'inheritancejs' ) ; function Base ( name , age ) { this . name = name ; this . age = age ; } Base ....

    JavaScript中数组继承的简单示例

    在写一些库时经常会用到树结构的数据,而且一些树形结构的数据对从根到叶的路径获取需求非常高。比如一个站点的整个路由表就是一棵这样的树,它的「路径」实际上就是 URL 中的 path...下面是一个简易实现: 运行 <

    由浅入深讲解Javascript继承机制与simple-inheritance源码分析

    下面我们由浅入深的系统掌握使用javascript继承的技巧。 1. 直接使用原型链 这是最简粗暴的一种方式,基本没法用于具体的项目中。一个简单的demo如下: function SuperType(){ this.property = true; } SuperType....

Global site tag (gtag.js) - Google Analytics