klass Class
js类创建,具有执行指针功能(解决了多级继承域对象的问题)
此外提供两种全局扩展方式:
1. 基于原形链的基类扩展,使用st.conf('oop-KlassBase'),可以取到基类对象进行扩展
2. 在类初始化时,对实例化的对象进行扩展,可以使用st.onKlassInit对象进行添加扩展方法。st.onKlassInit 是promiseEvent对象,st.onKlassInit(obj,config);
Constructor
klass
klass
(
-
name
-
prop
-
[parent]
-
[config]
)
Klass
Parameters:
name | type | flag | description |
---|---|---|---|
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
调用基类的方法
Parameters:
name | type | flag | description |
---|---|---|---|
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]
)
调用原型链方法
Parameters:
name | type | flag | description |
---|---|---|---|
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
类扩展方法
Parameters:
name | type | flag | description |
---|---|---|---|
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]
)
获取基类对象
Parameters:
name | type | flag | description |
---|---|---|---|
[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');