标签:
// 定义类A function A(a) { this.a = a; } // 为类A定义show方法 A.prototype.show = function() { alert("A: " + this.a); };
// 定义类B function B(a, b) { // 调用A的构造函数 A.apply(this, arguments); this.b = b; } // 链接A的原型 B.prototype = new A();
var b = new B(100, 200); b.show();此时。会运行定义在A中的show方法(显示A.a的值)。表示类B已经从类A中继承了show方法
// 覆盖show方法 B.prototype.show = function() { A.prototype.show.apply(this, arguments); alert("B: " + this.b); }; // 运行覆盖后的方法 b.show();在B的prototype中又一次定义show方法,即能够觉得B类覆盖了A类的show方法。
注意 A.prototype.show.apply(this, arguments) 这一句,实际上是利用了JS的原型特性。在B类对象中(以B类对象)运行了一次A类的show方法。
(以下代码灵感部分来源于ExtJS库,部分參考自prototype库)
// 定义根命名空间 ALV = {}; // 定义注冊命名空间的方法 ALV.namespace = function(ns) { var root = window; var parts = ns.split("."); for (var i = 0; i < parts.length; i++) { var p = parts[i]; if (!root[p]) { root[p] = {}; } root = root[p]; } };
// 合并对象成员 ALV.apply = function(obja, objb, def) { if (def) { ALV.apply(obja, def); } if (obja && objb && typeof objb === 'object') { for (var o in objb) { obja[o] = objb[o]; } } };
// 原型定义 ALV.define = function(clazz, config) { var parts = clazz.split("."); var root = window; for (var i = 0; i < parts.length - 1; i++) { root = root[parts[i]]; } var cn = parts[parts.length - 1]; if (!root[cn]) { root[cn] = function() {}; } clazz = root[cn]; // 将proto对象的成员赋值给类的原型 ALV.apply(clazz.prototype, config); return clazz; };
// 定义继承的方法 ALV.extend = function(base, child, proto) { // 将超类原型赋值给类的原型 var c = ALV.define(child); if (base && typeof base === "function") { c.prototype = new base(); } if (proto && typeof proto == "object") { ALV.apply(c.prototype, proto); } // 调用超类方法 c.prototype.callParent = function(args) { var m; for (var o in this) { if (this[o] === this.callParent.caller) { m = o; } } var method = base.prototype[m]; if (method && typeof method === "function") { method.apply(this, args); } }; };上述代码中。子类的 prototype 链接到了超类对象上。完毕了 prototype 的继承。而 callParent 方法中,通过对当前类调用方法的查找,找到方法名(m变量),再在超类的 prototype 中找到同名方法,利用超类方法的 apply 操作,在子类对象上完毕对超类方法的调用。
// 定义命名空间 ALV.namespace("Alvin.test"); // 定义超类 ALV.define("Alvin.test.A", { a: 100, show: function() { alert("A: " + this.a); } }); // 定义子类 ALV.extend(Alvin.test.A, "Alvin.test.B", { a: 100, b: 200, show: function() { this.callParent(arguments); alert("B: " + this.b); } }); // 实例化B类对象 var b = new Alvin.test.B(); b.show();
这样 B 类就可以自然地访问超类方法没有在指定到底有什么关注的超类的名称。
版权声明:本文博主原创文章,博客,未经同意不得转载。
标签:
原文地址:http://www.cnblogs.com/hrhguanli/p/4803467.html