js类创建,具有执行指针功能(解决了多级继承域对象的问题)

此外提供两种全局扩展方式:

1. 基于原形链的基类扩展,使用st.conf('oop-KlassBase'),可以取到基类对象进行扩展
2. 在类初始化时,对实例化的对象进行扩展,可以使用st.onKlassInit对象进行添加扩展方法。st.onKlassInit 是promiseEvent对象,st.onKlassInit(obj,config);

Properties

Events

Extends KlassBase
Defined in: src\base\oop.js:110
Module: OOP

Constructor

klass

klass
(
  • name
  • prop
  • [parent]
  • [config]
)
Klass

Defined in src\base\oop.js:110

Parameters:

nametypeflagdescription
name String

类名称

prop Object

类的属性和方法

[parent] Klass | Object | Function optional

父类

[config] Object optional

扩展参数

Returns:

[Klass]

返回类

Example:

            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 user = st.klass("user", {
                klassInit: function (name) {
                    this.name = name;
                },
                say: function (text) {
                    return this.name + ',' + text;
                }
            });

            var user1 = st.klass("user1", {
                name: 'user1',
                //自初始化方法为:klassInit,在实例化时执行
                klassInit: function  {
                }
            }, user);

            var roy = user1('roy');

            expect(roy.name).toBe('user1');
            expect(roy.say('hello')).toBe('user1,hello');
            var user = st.klass("user", {
                klassInit: function (name) {
                    this.name = name;
                },
                say: function (text) {
                    return this.name + ',' + text;
                }
            });

            expect(user.fn._$klass).toBe(true);
            expect(user.fn._$kName).toBe('user');
            expect(user.fn._$inheirts + '').toBe('user');
            //创建一个class
            var User = st.klass('user', {
                klassInit: function (name) {
                    this.name = name;
                },
                say: function (text) {
                    return this.name + ',' + text;
                }
            });

            //实例化一个User
            var xiaoming = new User('小明');

            //方法实例化
            var xiaozhang = User('小张');

            //多级继承例子。在多级继承中有一种场景每个子类方法都会调用父类的方法,而方法中又会使用到当前对象的属性,则问题就来了;
            //如果是采用的parent.xxx然后传递this下的属性值过去,则没太大的问题。backbone就采用的这种。
            //另外像base.js直接改写原始方法,将父对象封入闭包中,也无问题。只是这种限制比较大,只能调用父类的同名方法。
            //而dojo采用的是this.parent.xxx.call(this)的方式,则就会悲剧了,死循环就来了。
            //导致这样的原因就是将this带入parent方法后,父类又执行this.parent。而这是this则是子类的对象,那么方法就只会不停的调用parent的方法。
            //在smartjs中klass调用父类方法由callBae这个方法来代理,同时使用指针来记录方法的执行轨迹,这样保证了从子到根的各级调用

            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");

Methods

callBase

callBase
(
  • fnName
  • [baseName]
  • [args]
)
Object

Inherited from klassBase: src\base\oop.js:60

调用基类的方法

Parameters:

nametypeflagdescription
fnName String

方法名称

[baseName] String optional

基类名称

[args] Array optional

方法参数数组

Returns:

[Object]

执行结果

Example:

            var Animate = st.klass("Animate", {
                klassInit: function (name) {
                    this.name = name;
                },
                say: function (text) {
                    return this.name + ':' + text;
                }
            });

            //继承user
            var Bird = st.klass("Bird", {
                //重写say方法
                say: function (text) {
                    //调用基类方法
                    return '[Bird]' + this.callBase('say', [text]);
                }
            }, Animate);

            var chicken = new Bird('chicken');
            expect(chicken.say('hello')).toBe('[Bird]chicken:hello');
            //创建一个class
            var User = st.klass('user', {
                klassInit: function (name) {
                    this.name = name;
                },
                say: function (text) {
                    return this.name + ',' + text;
                }
            });

            //实例化一个User
            var xiaoming = new User('小明');

            //方法实例化
            var xiaozhang = User('小张');

            //多级继承例子。在多级继承中有一种场景每个子类方法都会调用父类的方法,而方法中又会使用到当前对象的属性,则问题就来了;
            //如果是采用的parent.xxx然后传递this下的属性值过去,则没太大的问题。backbone就采用的这种。
            //另外像base.js直接改写原始方法,将父对象封入闭包中,也无问题。只是这种限制比较大,只能调用父类的同名方法。
            //而dojo采用的是this.parent.xxx.call(this)的方式,则就会悲剧了,死循环就来了。
            //导致这样的原因就是将this带入parent方法后,父类又执行this.parent。而这是this则是子类的对象,那么方法就只会不停的调用parent的方法。
            //在smartjs中klass调用父类方法由callBae这个方法来代理,同时使用指针来记录方法的执行轨迹,这样保证了从子到根的各级调用

            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");

callProto

callProto
(
  • name
  • [args]
)

Inherited from klassBase: src\base\oop.js:22

调用原型链方法

Parameters:

nametypeflagdescription
name String

需要执行的原型链方法名

[args] Array optional

执行参数

Returns:

[object] 返回执行结果

Example:

            var Animate = st.klass("Animate", {
                klassInit: function (name) {
                    this.name = name;
                },
                say: function (text) {
                    return this.name + ':' + text;
                }
            });

            var chicken = new Animate('chicken');
            chicken.say = function (text) {
                //调用原型链方法
                return '[Bird]' + this.callProto('say', [text]);
            };

            expect(chicken.say('hello')).toBe('[Bird]chicken:hello');

extend

extend
(
  • prop
)
chainable

Inherited from klassBase: src\base\oop.js:95

类扩展方法

Parameters:

nametypeflagdescription
prop Object

扩展的属性和方法对象

Example:

            var Animate = st.klass("Animate", {
                klassInit: function (name) {
                    this.name = name;
                },
                say: function (text) {
                    return this.name + ':' + text;
                }
            });

            var chicken = new Animate('chicken');

            //扩展等同于 chicken.say = xxx
            chicken.extend({
                say: function (text) {
                    return 'hello';
                }
            });

            expect(chicken.say('hello')).toBe('hello');

getBase

getBase
(
  • [baseName]
)

Inherited from klassBase: src\base\oop.js:35

获取基类对象

Parameters:

nametypeflagdescription
[baseName] String optional

基类名称,不设置则返回父类

Returns:

[object] 返回基类

Example:

            var Animate = st.klass("Animate", {
                klassInit: function (name) {
                    this.name = name;
                },
                say: function (text) {
                    return this.name + ':' + text;
                }
            });

            //继承user
            var Bird = st.klass("Bird", {
                //重写say方法
                say: function (text) {
                    //根据名称向上找到父类原型
                    var parent = this.getBase('Animate');

                    //调用原型链方法
                    return '[Bird]' + parent.say.call(this, text);
                }
            }, Animate);

            var chicken = new Bird('chicken');
            expect(chicken.say('hello')).toBe('[Bird]chicken:hello');
Top