zoukankan      html  css  js  c++  java
  • smartjs 0.2 OOP讲解

    SmartJS2.0加入OOP的功能。OOP包括klass与factory两个对象。

    Klass 类继承

    与其他的类继承相比,smartjs使用了执行指针的概念(后面例子中会介绍),另外提供base基类和初始化控制的扩展功能。

    首先来看看接口:

      var _klass = st.klass(name, prop, parent, config);
        //new _klass() 与 _klass()效果相同,实现了自初始化功能更
        var obj = new _klass();

    name : 类名

    prop : 类属性&方法

    parent :[可选],父类对象

    config :[可选],类配置参数,做动态扩展使用;后续版本会加入内容;

    注意自初始化方法为:klassInit,在实例化时执行

    实例化类后,对象会具有以下方法和属性:

    //获取基类对象
    obj.getBase(baseName);


    //执行基类对象
    obj.callBase(fnName, baseName, args);


    //对象扩展方法
    obj.extend(prop);


    //父类对象
    obj._$super


    //类标示
    obj._$klass : bool


    //类名
    obj._$kName : string


    //继承链
    obj._$inheirts : array

     

    此外两种全局扩展方式:

    1. 基于原形链的基类扩展,使用st.conf('oop-KlassBase'),可以取到基类对象进行扩展

    2. 在类初始化时,对实例化的对象进行扩展,可以使用st.onKlassInit对象进行添加扩展方法。

    st.onKlassInit 是promiseEvent对象,参数为:obj,conf

      obj:类对象

      conf:即klass定义的时候的conf

     

     

    代码示例

    基础

     var user = st.klass("user", {
                klassInit: function(name) {
                    this.name = name;
                },
                say: function(text) {
                    return this.name + ',' + text;
                }
            });
    
                 var user1 = new user('roy'),
                    //执行方法与实例化等效
                    user2 = user('tracy');
    
            expect(user1.name).toBe('roy');
            expect(user1.say('hello')).toBe('roy,hello');
            expect(user2.name).toBe('tracy');
            expect(user2.say('hello')).toBe('tracy,hello');

    综合例子

    var user1 = st.klass("user1", {
                name: 'user1',
                //自初始化方法为:klassInit,在实例化时执行
                klassInit: function() {}
            }, user);
    
            //继承测试
            it("inheirt", function() {
    
                var roy = user1('roy');
    
                expect(roy.name).toBe('user1');
                expect(roy.say('hello')).toBe('user1,hello');
            })
    
            //调用父类测试
            it("klassBase - callBase", function() {
                var roy = user1();
                roy.callBase('klassInit', ['roy']);
                expect(roy.name).toBe('roy');
            })
    
            //扩展例子
            it("klassBase - extend", function() {
                var roy = user1();
                roy.extend({
                    say: function() {
                        return "extend";
                    }
                });
    
                expect(roy.say()).toBe('extend');
                expect(roy.callBase('say', ['extend'])).toBe("user1,extend");
            })

    多级继承例子。在多级继承中有一种场景每个子类方法都会调用父类的方法,而方法中又会使用到当前对象的属性,则问题就来了;

    如果是采用的parent.xxx然后传递this下的属性值过去,则没太大的问题。backbone就采用的这种。

    另外像base.js直接改写原始方法,将父对象封入闭包中,也无问题。只是这种限制比较大,只能调用父类的同名方法。

    而dojo采用的是this.parent.xxx.call(this)的方式,则就会悲剧了,死循环就来了。

    导致这样的原因就是将this带入parent方法后,父类又执行this.parent。而这是this则是子类的对象,那么方法就只会不停的调用parent的方法。

    有兴趣的朋友可以下去看下,项目上面使用的继承会出现此问题。如果有更好的方案,希望能分享。

    smart采用类继承的方式与dojo比较类似,但是调用父类方法由callBae这个方法来代理,同时使用指针来记录方法的执行轨迹,这样保证了从子到根的各级调用。

    var user = st.klass("user", {
                    klassInit: function(name) {
                        this.name = name;
                    },
                    say: function(text) {
                        return this.name + ',' + text;
                    }
                })
    
                var user2 = st.klass('user2', {
                    say: function(text) {
                        return this.callBase('say', [text]) + "-lv2";
                    }
                }, user);
    
                var user3 = st.klass('user3', {
                    say: function(text) {
                        return this.callBase('say', [text]) + "-lv3";
                    }
                }, user2);
    
                var user4 = st.klass('user4', {
                    say: function(text) {
                        return this.callBase('say', [text]) + "-lv4";
                    }
                }, user3);
    
                var roy = new user4('roy');
                expect(roy._$inheirts + '').toBe('user4,user3,user2,user');
                //依次执行到根,正确将当前的this对象的值输出
                expect(roy.say('hello')).toBe('roy,hello-lv2-lv3-lv4');
    
                //从3级开始执行
                expect(roy.callBase('say', ['hello'])).toBe("roy,hello-lv2-lv3");
    
                //指定从user开始执行
                expect(roy.callBase('say', 'user', ['hello'])).toBe("roy,hello");
    
                //上向略过2级执行
                expect(roy.callBase('say', 2, ['hello'])).toBe("roy,hello-lv2");
  • 相关阅读:
    2,进程----multiprocessing模块介绍
    1,进程----进程理论知识
    对ORM的理解
    对queryset的理解
    个人总结-10-代码测试整合
    个人总结-9-session的使用,十天免登陆
    个人总结-8-重新写注册和登录界面
    个人总结-7- 实现图片在MySQL数据库中的存储,取出以及显示在jsp页面上
    从人机交互看对搜狗输入法的使用感受
    个人总结6-验证码制作总结
  • 原文地址:https://www.cnblogs.com/zhh8077/p/3788541.html
Copyright © 2011-2022 走看看