`

继承体系 --class.js

    博客分类:
  • RIA
 
阅读更多

//继承
 //实现singlaton
 //可以调用基类函数
 //JavaScript通过构造函数和原型的方式模拟实现了类的功能。
  
 
  var Class = (function(){
 
     //IE不会遍历几个特殊属性:"constructor", "toString", "valueOf"
      var IS_DONTENUM_BUGGY = void function(){
         for (var p in { toString: 1}) return false;
         return true;
     }(); 
     function create(options){
         var options = options || {}, uniqueInstance = null;
         //判定是否需要实现单例
          var singleton = !!options.singleton;
         delete options.singleton;
         //父类
         var superclass = options.inherit || {};
         delete options.inherit;
         
         function klass(){
             if (!singleton)  this.init.apply(this, arguments);
         }
         //添加类方法
         $U.extend(klass, Class.Methods);
         //是否继承
         if ($U.isFunction(superclass)) {
             var bridge = function(){};
             bridge.prototype = superclass.prototype;
             klass.prototype = new bridge;
             klass.superclass = superclass;
         }
         //添加原型方法
         klass.addMethods(options);
         
         if (!klass.prototype.init) 
             klass.prototype.init = function(){
             };
         //修正constructor    
         klass.prototype.constructor = klass;
         //__proto__是什么?我们在这里简单地说下。每个对象都会在其内部初始化一个属性,就是__proto__,当我们访问一个对象的属性时,如果
         //这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性,这个__proto__又会有自己的__proto__,于是就这样
         //一直找下去,也就是我们平时所说的原型链的概念。
         //按照标准,__proto__是不对外公开的,也就是说是个私有属性,但是Firefox的引擎将他暴露了出来成为了一个共有的属性,
         //我们可以对外访问和设置。
         
         //修复IE与Opera中的第二条原型链
         if (!klass.prototype.__proto__) klass.prototype.__proto__ = klass.prototype;
         
         
         //处理函数:如果singleton模式,则private constructor
         return singleton ? {
             getInstance: function(){
                 if (!uniqueInstance) {// Instantiate only if the instance doesn't exist.
                     uniqueInstance = new klass;
                     uniqueInstance.init.apply(uniqueInstance, arguments);
                 }
                 return uniqueInstance;
             }
         } : klass;
     }
     function addMethods(source){
         var ancestor = this.superclass && this.superclass.prototype, properties = $U.keys(source);
         //处理IE不能遍历的特殊属性。
         if (IS_DONTENUM_BUGGY) {
             if (source.toString != Object.prototype.toString) 
                 properties.push("toString");
             if (source.valueOf != Object.prototype.valueOf) 
                 properties.push("valueOf");
         }
         for (var i = 0, length = properties.length; i < length; i++) {
             var property = properties[i], value = source[property];
             //在C#中,如果子类有意隐藏基类成员,使用关键字"new"
             //使用base关键字显示调用基类构造函数
             //这这里约定如果子类方法第一个参数是“$super”,则调用父类的方法.
             if (ancestor && $U.isFunction(value) && (value.argumentNames()[0] === "$super")) {
                 var method = value;
                 //var f = (function(m){ return function(){ return ancestor[m].apply(this, arguments)}})(property)
                 //f.wrap(method)
                 
                 //F.prototype[name] = (function(name, fn) {
                 //    return function() {
                 //        var that = this;
                 //        $super = function() {
                 //            return baseClass.prototype[name].apply(that, arguments);
                 //        };
                 //        return fn.apply(this, Array.prototype.concat.apply($super, arguments));
                 //    };
                 //})(name, prop[name]);
                 
                 
                 //总之,实现把基类函数作为子函数的第一个参数,以此调用父函数。
                 value = ancestor[property].wrap(method);
                 value.valueOf = method.valueOf.bind(method);
                 // 因为我们改变了函数体,所以重新定义函数的toString方法
                 // 这样用户调用函数的toString方法时,返回的是原始的函数定义体
                 value.toString = method.toString.bind(method);
             }
             this.prototype[property] = value;
         }
         return this;
     }
     return {
         create: create,
         Methods: {
             addMethods: addMethods
         }
     };
 })()
 
 
 //继承
 //实现singlaton
 
 var F = function(){
 };
 F.prototype.getInstance = function(){
 
     var instance = null;
     
     return function(){
         if (!instance) 
             instance = new this;
         return instance;
     };
     
 }();
 
分享到:
评论

相关推荐

    Note-Frontend:前端知识案例汇总--实践很重要!!!

    前端知识体系一.基础知识5.相关框架3.React二.标准1.ECMA1.原型和原型链2.作用域和闭包3.异步4.ES61.let和const2.解构赋值3.模板字符串4.箭头函数5.展开运算符6.数组的方法7.对象8.继承9.类的编译10.类的继承11....

    asp.net面试题

    然而,结构在几个重要方面不同于类:结构为值类型而不是引用类型,并且结构不支持继承。结构的值存储在“在堆栈上”或“内联”。细心的程序员有时可以通过聪明地使用结构来增强性能。 12.概述.NET里对 remoting 和 ...

    介绍一个简单的JavaScript类框架

    在写work-in-progress JavaScript book一书时,对于javascript继承体系,我花费了相当的时间,并在该过程中研究了各种不同的模拟经典类继承的方案。这些技术方案中,我最为推崇的是base2与Prototype的实现。 从这些...

    Cocos2D-X游戏开发技术精解

    1.8 Cocos2D-X引擎的体系 18 1.9 Cocos2D-X引擎的版权声明 19 1.10 本章小结 20 第2章 Cocos2D-X引擎的 开发环境 21 2.1 跨平台的开发 21 2.2 建立开发环境 23 2.2.1 PC开发环境 23 2.2.2 Android开发环境 26 2.2.3 ...

    asp.net知识库

    革新:.NET 2.0的自定义配置文件体系初探 关于如何在ASP.NET 2.0中定制Expression Builders 怎么在ASP.NET 2.0中使用Membership asp.net 2.0-实现数据访问(1) ASP.NET 2.0 新特性 .NET 2.0里使用强类型数据创建...

    picket:Picket使您可以使用JavaScript创建大规模的面向对象的体系结构

    纠察Picket使您可以使用JavaScript创建大规模的面向对象的体系结构。 当前功能列表包括以下内容; 类,抽象类,接口,继承,类属性/字段,类方法,类构造函数,类常量,类事件,抽象类成员,属性类型,方法参数类型...

    深入浅出ES6 简体中文

    标准委员会甚至为JavaScript增加了类特性,有关这一方面的特性褒贬不一,Douglas Crockford曾在2014年的Nordic.js大会发表了题为《The Better Parts》的演讲,重新阐述了他个人对于ECMAScript 6的看法,他认为Class...

    亮剑.NET深入体验与实战精要2

    2.5 abstract class与interface 91 2.6 公共变量与属性的区别 93 2.7 参数修饰符params、out和ref的区别 96 2.8 值类型和引用类型的区别 100 2.9 结构与类的区别 103 2.10 Dispose()和Close()、Finalize()的 区别 ...

    亮剑.NET深入体验与实战精要3

    2.5 abstract class与interface 91 2.6 公共变量与属性的区别 93 2.7 参数修饰符params、out和ref的区别 96 2.8 值类型和引用类型的区别 100 2.9 结构与类的区别 103 2.10 Dispose()和Close()、Finalize()的 区别 ...

    高性能多级网关与多级缓存架构落地实战(完结+附电子书)

    第一步,把function 改为class,然后去掉括号,让app继承react.component。 第二步,使用react 组件类的成员、render函数,把retrun的jsx代码全部包裹起来。 第三步需要我们创建构建函数,在构建函数中初始化state...

    基于J2EE框架的个人博客系统项目毕业设计论文(源码和论文)

    真正的客户机/服务器体系结构。  2.图形化用户界面,使系统管理和数据库管理更加直观、简单。  3.丰富的编程接口工具,为用户进行程序设计提供了更大的选择余地。  4.SQL Server与Windows NT完全集成,利用...

    ES6新特性之模块Module用法详解

    ES6的Class只是面向对象编程的语法糖,升级了ES5的构造函数的原型链继承的写法,并没有解决模块化问题。Module功能就是为了解决这个问题而提出的。 历史上,JavaScript一直没有模块(module)体系,无法将一个大程序...

Global site tag (gtag.js) - Google Analytics