zoukankan      html  css  js  c++  java
  • Simple JavaScript Inheritance--一个极简JS面向对象-类库

    面向对象

    面向对象思想的几个重要特征(针对类的要求):

    抽象-封装、信息隐藏(将内部实现的方法和数据隐藏, 定义开放的接口)

    继承-子类可以使用父类的资源,并可以定制自己的资源, 资源包括方法和数据

    多态-重载(同名函数)、覆盖(继承的基础上重写父类函数)

    JS与面向对象

    javascript使用prototype实现类的继承功能, 非经典面向对象语言的类的形式, 使用方法也不同, 导致使用较困难。

    请参考大师的《深入理解javascript原型和闭包系列http://www.cnblogs.com/wangfupeng1988/p/4001284.html

    于是各种库都提供了自己实现类库, 例如:

    1、 jquery class create: https://github.com/protonet/jquery-class-create

    使用Class.Create创建实用类, 即实例的构造函数, 其缺点是用来jquery库

    // properties are directly passed to `create` method
      var Person = Class.create({
        initialize: function(name) {
          this.name = name;
        },
        say: function(message) {
          return this.name + ': ' + message;
        }
      });
      
      // when subclassing, specify the class you want to inherit from
      var Pirate = Class.create(Person, {
        // redefine the speak method
        say: function($super, message) {
          return $super(message) + ', yarr!';
        }
      });
      
      var john = new Pirate('Long John');
      john.say('ahoy matey');
      // -> "Long John: ahoy matey, yarr!"

    2、 prototypejs :  http://prototypejs.org/learn/class-inheritance

    作为prototypejs库的一个功能提供, 使用上跟jquery class create接口一致。

    此库还提供, ajax和DOM优雅的接口, 消灭客户端开发的复杂性。

    这两个库 要么依赖其他库, 要么自身库功能繁杂, 体积都大, 故单独使用的需求不满足。

    本文介绍一个不依赖任何库、且实现上只包括类继承的库,  这位大神开发的独立库: John Resig http://ejohn.org/

    Simple JavaScript Inheritance

    Simple JavaScript Inheritance

    此库的官网为

    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
    
        // Should all be true
    
        p instanceof Person && p instanceof Class &&
    
        n instanceof Ninja && n instanceof Person && n instanceof Class

    实现说明:

    1、 创建构造函数必须简单, 构造函数只提供 init初始化方法。

    2、 创建新类,必须扩展一个存在的类, 调用extend。

    3、 所有的继承与唯一的祖先 Class。 创建的新类必须是Class的子类。

    4、 子类中访问父类的同名方法(即被覆盖)必须提供。 通过this.super子类同名方法中调用父类同名方法。

    实现要点

     实现代码:

        /* 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;}) ? /_super/ : /.*/;
    
          // The base Class implementation (does nothing)
    
          this.Class = function(){};
    
          // Create a new Class that inherits from this class
    
          Class.extend = function(prop) {
    
            var _super = this.prototype;
    
            // Instantiate a base class (but only create the instance,
    
            // don't run the init constructor)
    
            initializing = true;
    
            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
    
              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
    
              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
    
            Class.extend = arguments.callee;
    
            return Class;
    
          };
    
        })();

    要点:

    1、初始化调用 xx.extend{init:function(){}} 中的 init执行初始化

        // The dummy class constructor
    
        function Class() {
    
          // All construction is actually done in the init method
    
          if ( !initializing && this.init )
    
            this.init.apply(this, arguments);
    
        }

    2、 子类通过 this._super 访问父类的同名函数, 例如:

        var Person = Class.extend({
    
          init: function(isDancing){
    
            this.dancing = isDancing;
    
          }
    
        });
    
        var Ninja = Person.extend({
    
          init: function(){
    
            this._super( false );
    
          }
    
        });
    
        var p = new Person(true);
    
        p.dancing; // => true
    
        var n = new Ninja();
    
        n.dancing; // => false

    如下, 将儿子有此函数, 父亲也有此同名函数时候, 此函数中记录函数地址到this._super中。

          // Check if we're overwriting an existing function
    
          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];
    
        }
  • 相关阅读:
    Go 函数方法
    rz上传文件乱码
    pip问题:ImportError: cannot import name main
    docker启动报错 docker: Error response from daemon: OCI runtime create failed: container_linux.go:348
    python遍历列表删除多个元素的坑
    python写入csv文件时的乱码问题
    python中的exec()函数和eval()函数
    tornado的IOLoop.instance()方法和IOLoop.current()方法区别
    安装mysql-python时报错
    python将科学计数法表示的数值的字符串转换成数值型数据
  • 原文地址:https://www.cnblogs.com/lightsong/p/4666112.html
Copyright © 2011-2022 走看看