[转载]淘宝Kissy框架分析【三】 – BlueDream – 博客园.
继续分析kissy.js
6.extend函数
作用: 这个extend函数是kissy框架面向对象的核心.实现了继承机制.kissy的继承使用了 对象冒充 + 原型继承的混合模式.
原理:
var OP = Object.prototype,
// O方法作用是 用一个壳包装函数. 让其原型引用到父类的的原型
// 然后将这个原型再覆盖给子类的原型. 壳函数的好处就是 new的时候 省空间. 因为构造为空
O = function (o) {
function F() {}
F.prototype = o;
return new F();
},
sp = s.prototype,
rp = O(sp);
// 因为原型被覆盖.所以原型的prototype指向了F 要修正回来
// 具体constructor的原理可参考http://www.cnblogs.com/objectorl/archive/2009/09/02/1632715.html
rp.constructor = r; // 将子类的自定义属性superclass指向父类的原型 这样就方便引用到原型实例
// r.superclass.constructor.call(this, options) 就可以实现属性冒充.继承父类的构造属性
r.superclass = sp; // 如果父类不是Object但constructor却指向了Object, 表示父类的原型也被覆盖了 所以要保证正确
// 这样r.superclass.constructor才能正确指向父类
if (s !== Object && sp.constructor === OP.constructor) {
sp.constructor = s;
}
// O方法作用是 用一个壳包装函数. 让其原型引用到父类的的原型
// 然后将这个原型再覆盖给子类的原型. 壳函数的好处就是 new的时候 省空间. 因为构造为空
O = function (o) {
function F() {}
F.prototype = o;
return new F();
},
sp = s.prototype,
rp = O(sp);
r.prototype
= rp;// 因为原型被覆盖.所以原型的prototype指向了F 要修正回来
// 具体constructor的原理可参考http://www.cnblogs.com/objectorl/archive/2009/09/02/1632715.html
rp.constructor = r; // 将子类的自定义属性superclass指向父类的原型 这样就方便引用到原型实例
// r.superclass.constructor.call(this, options) 就可以实现属性冒充.继承父类的构造属性
r.superclass = sp; // 如果父类不是Object但constructor却指向了Object, 表示父类的原型也被覆盖了 所以要保证正确
// 这样r.superclass.constructor才能正确指向父类
if (s !== Object && sp.constructor === OP.constructor) {
sp.constructor = s;
}
测试用例:
J1616.add(‘view‘, function(J) {
var SP = Base.prototype;
// 父类构造器
function Base(name, age) {
this.name = name;
this.age = age;
};
// 父类原型
J.mix(SP, {
showName: function() {
alert(this.name);
}
}); // 子类继承父类.并实现自己的方法
function Children(name, age) {
// 对象冒充抄写构造属性
Children.superclass.constructor.call(this, name, age);
};
// 继承父类
J.extend(Children, Base);
// 添加showAge方法
J.augment(Children, {
showAge: function() {
alert(this.age)
}
});
// 实例化子类
var child = new Children(‘j1616‘, 23);
child.showName(); // 从父类继承而来 j1616
child.showAge(); // 后期扩展而来 23
});
var SP = Base.prototype;
// 父类构造器
function Base(name, age) {
this.name = name;
this.age = age;
};
// 父类原型
J.mix(SP, {
showName: function() {
alert(this.name);
}
}); // 子类继承父类.并实现自己的方法
function Children(name, age) {
// 对象冒充抄写构造属性
Children.superclass.constructor.call(this, name, age);
};
// 继承父类
J.extend(Children, Base);
// 添加showAge方法
J.augment(Children, {
showAge: function() {
alert(this.age)
}
});
// 实例化子类
var child = new Children(‘j1616‘, 23);
child.showName(); // 从父类继承而来 j1616
child.showAge(); // 后期扩展而来 23
});
7.namespace函数
作用: 建立命名空间. 如果该命名空间存在则直接引用.不覆盖.
* S.namespace(‘KISSY.app’); // returns KISSY.app
* S.namespace(‘app.Shop’); // returns KISSY.app.Shop
测试用例:
J1616.namespace(‘www‘);
J1616.www.search = {
version: ‘0.0.1‘
};
alert(J1616.www.search.version) // 0.0.1
J1616.www.search = {
version: ‘0.0.1‘
};
alert(J1616.www.search.version) // 0.0.1
8.app函数
作用:建立各个分支模块的app应用.并会对app的_init, add, namespace方法重写.并执行_init
测试用例:
J1616.app(‘J16‘); // 建立一个J16 App
J16.namespace(‘www‘); // 在J16下面建立www命名空间
J16.www.music = { // J16App的www命名空间下的music模块
version: ‘0.0.1‘
};
J16.namespace(‘www‘); // 在J16下面建立www命名空间
J16.www.music = { // J16App的www命名空间下的music模块
version: ‘0.0.1‘
};
alert(J16.www.music.version);
// 0.0.1
剩余两个log函数和error函数没啥可说的.至此kissy.js就结束了.
紧接着我们要开始对kissy-lang.js进行分析.