1:如何模拟一个类
在sencha touch2 系列里面定义一个类和new出这个类的对象
Ext.define(
"Animal", {
config: {
name: null
},
constructor: function(config) {
this.initConfig(config);
},
speak: function() {
console.log('说点什么');
}
}
)
var my=Ext.create("Animal",{name:"bb"})
my.speak();
上面代码里面constructor在create的时候会自动调用,然后初始化config对象配置的属性。constructor完全就像面对象里面的构造函数……
下面我模拟一下
// 在sencha中new一个对象传了两个参数Ext.create("Animal",{name:"bb"})
// 这里就不模拟sencha的命名空间了,所以生成该类的对象的时候传一个配置对象即可
// 把命名空间(mss)和命名单独提取出来,new mss.define({});
var mss = {} //建立一个命名空间
mss.define = function(config) {
if(typeof config !== 'object') {
console.log('参数错误');
return;
}
var interface = function() { //当new 该define返回的函数,会自动执行atrr和init
this.attr && this.attr();
this.init && this.init.apply(this, arguments);
}
for(var i in config) {
config.hasOwnProperty(i) &&(interface.prototype[i] = config[i]);
}
return interface;
}
var Car = mss.define({
attr: function() {
this.type = '汽车';
},
init: function() {
console.log(this.type);
},
speank: function() {
console.log('我是' + this.type);
}
});
var car1 = new Car();
car1.speank();
输出
汽车
我是汽车
[Finished in 0.1s]
这样就模拟成了:define一个类,然后new出来调用其方法;
2:如何在此基础上继承一个类
首先看看sencha touch2系列的继承
Ext.define(
"Person", {
extend: "Animal",
speak: function() {
console.log('我是人');
}
}
)
加多一个属性extend搞定。
下面在mss.define模拟一下
// 在sencha中new一个对象传了两个参数Ext.create("Animal",{name:"bb"})
// 这里就不模拟sencha的命名空间了,所以生成该类的对象的时候传一个配置对象即可
// 把命名空间(mss)和命名单独提取出来,new mss.define({});
var _mss = {} //建立一个命名空间
_mss.Define = function(parClass, curConfig) {
// 若sup 是个object,表示这是一个新类
// 若sup 是个function,表示这是一个继承
if(typeof parClass === 'object') {
curConfig = parClass;
parClass = function() {};
}
// 定义返回类
// 当new 该define返回的函数,会自动执行atrr和init
var interface = function() {
this.attr && this.attr();
this.init && this.init.apply(this, arguments);
}
// 返回类继承 parClass
interface.prototype = new parClass();
// 为返回类包含的两个初始化函数定义基础方法
// 获得继承的init方法 和attr方法
// 如果parClass存在init方法,那么nterface.prototype.init
// 和new parClass().init相等
var parInit = interface.prototype.init || function() {};
var curInit = curConfig.init || function() {};
var parAttr = interface.prototype.attr || function() {};
var curAttr = curConfig.attr || function() {};
// 为返回类原型初始化当前属性,这里注意可能被后面的方法重写
for(var i in curConfig) {
curConfig.hasOwnProperty(i) && (interface.prototype[i] = curConfig[i]);
}
// 如果当前返回类已经继承了init,重写该方法
if(arguments.length && arguments[0].prototype && arguments[0].prototype.init === parInit) {
interface.prototype.init = function() {
var scope = this;
var args = [function() {
parInit.apply(scope, arguments);
}];
var slice = [].slice;
curInit.apply(scope, args.concat(slice.call(arguments)));
}
}
// 如果当前返回类已经继承了attr,重写attr 或者是首次构造改方法(新类)
interface.prototype.attr = function() {
parAttr.call(this);
curAttr.call(this);
}
// 继承父类的成员属性
for(var i in parClass) {
parClass.hasOwnProperty(i) && (interface[i] = parClass[i]);
}
return interface;
}
var Car = _mss.Define({
attr: function() {
this.type = '汽车';
},
init: function() {
console.log(this.type);
},
speank: function() {
console.log('我是' + this.type);
}
});
var car1 = _mss.Define(Car, {
})
new car1().speank();
输出
汽车
我是汽车
[Finished in 0.1s]
对于call实现继承
interface.prototype.attr = function() {
parAttr.call(this);
curAttr.call(this);
}
在Chorome控制台打印这段代码就可以解释一下这段代码了
var _Attr = function() {
this.a = 1;
}
var B = function() {
this.attr();
};
B.prototype.attr = function(){_Attr.call(this);}
console.log(new B());
VM665:9 B {a: 1}a: 1__proto__: Battr: (){_Attr.call(this);}constructor: () {__proto__: Object