JavaScript继承的一些工具函数
2012-06-21 15:35
381 查看
在阅读精通JavaScript(图灵计算机科学丛书)里面有讲解javascript继承的一些东东。
其一是讲解DouglasCrockford的js
代码如下:
调用代码:
第二个工具函数是base库
代码:
/*
Base.js, version 1.1a
Copyright 2006-2010, Dean Edwards
License: http://www.opensource.org/licenses/mit-license.php */
var Base = function() {
// dummy
};
Base.extend = function(_instance, _static) { // subclass
var extend = Base.prototype.extend;
// build the prototype
Base._prototyping = true;
var proto = new this;
extend.call(proto, _instance);
proto.base = function() {
// call this method from any other method to invoke that method's ancestor
};
delete Base._prototyping;
// create the wrapper for the constructor function
//var constructor = proto.constructor.valueOf(); //-dean
var constructor = proto.constructor;
var klass = proto.constructor = function() {
if (!Base._prototyping) {
if (this._constructing || this.constructor == klass) { // instantiation
this._constructing = true;
constructor.apply(this, arguments);
delete this._constructing;
} else if (arguments[0] != null) { // casting
return (arguments[0].extend || extend).call(arguments[0], proto);
}
}
};
// build the class interface
klass.ancestor = this;
klass.extend = this.extend;
klass.forEach = this.forEach;
klass.implement = this.implement;
klass.prototype = proto;
klass.toString = this.toString;
klass.valueOf = function(type) {
//return (type == "object") ? klass : constructor; //-dean
return (type == "object") ? klass : constructor.valueOf();
};
extend.call(klass, _static);
// class initialisation
if (typeof klass.init == "function") klass.init();
return klass;
};
Base.prototype = {
extend: function(source, value) {
if (arguments.length > 1) { // extending with a name/value pair
var ancestor = this[source];
if (ancestor && (typeof value == "function") && // overriding a method?
// the valueOf() comparison is to avoid circular references
(!ancestor.valueOf || ancestor.valueOf() != value.valueOf()) &&
/\bbase\b/.test(value)) {
// get the underlying method
var method = value.valueOf();
// override
value = function() {
var previous = this.base || Base.prototype.base;
this.base = ancestor;
var returnValue = method.apply(this, arguments);
this.base = previous;
return returnValue;
};
// point to the underlying method
value.valueOf = function(type) {
return (type == "object") ? value : method;
};
value.toString = Base.toString;
}
this[source] = value;
} else if (source) { // extending with an object literal
var extend = Base.prototype.extend;
// if this object has a customised extend method then use it
if (!Base._prototyping && typeof this != "function") {
extend = this.extend || extend;
}
var proto = {toSource: null};
// do the "toString" and other methods manually
var hidden = ["constructor", "toString", "valueOf"];
// if we are prototyping then include the constructor
var i = Base._prototyping ? 0 : 1;
while (key = hidden[i++]) {
if (source[key] != proto[key]) {
extend.call(this, key, source[key]);
}
}
// copy each of the source object's properties to this object
for (var key in source) {
if (!proto[key]) extend.call(this, key, source[key]);
}
}
return this;
}
};
// initialise
Base = Base.extend({
constructor: function() {
this.extend(arguments[0]);
}
}, {
ancestor: Object,
version: "1.1",
forEach: function(object, block, context) {
for (var key in object) {
if (this.prototype[key] === undefined) {
block.call(context, object[key], key, object);
}
}
},
implement: function() {
for (var i = 0; i < arguments.length; i++) {
if (typeof arguments[i] == "function") {
// if it's a function, call it
arguments[i](this.prototype);
} else {
// add the interface using the extend method
this.prototype.extend(arguments[i]);
}
}
return this;
},
toString: function() {
return String(this.valueOf());
}
});
调用代码:
var Person = Base.extend({
constructor: function (name) { this.name = name; },
getName: function () { return this.name; }
});
var User = Person.extend({
constructor: function (name, password) {
this.base(name);
this.password = password;
},
getPassWord: function () { return this.password; }
});
var p = new Person("123");
alert(p.getName());
var u = new User("456", "abc");
alert(u.getName());
alert(u.getPassWord());
有关base的详细介绍:http://dean.edwards.name/weblog/2006/03/base/
其一是讲解DouglasCrockford的js
代码如下:
//简单的辅助函数,让你可以将新函数绑定到对象prototype上 Function.prototype.method = function (name, func) { this.prototype[name] = func; return this; } //一个相当复杂的函数,允许你方便地从其他对象继承函数, //同时仍然可以调用属于父对象的那些方法 Function.method('inherits', function (parent) { var d = {}; //记录我们目前所在父层次的级数 var p = (this.prototype = new parent()); //继承父对象的方法 //创建一个新的名位uber的特权函数 //调用它时会执行所有在继承时被重写的函数 this.method("uber", function uber(name) { if (!(name in d)) { d[name] = 0; //继承级数默认为0 } var f, /*要执行的函数*/r, /*函数返回值*/t = d[name], v = parent.prototype; /*父对象的prototype*/ if (t) { //如果我们已经在某个uber函数内 上溯到必要的级数已找到原始的prototype while (t) { v = v.constructor.prototype; t -= 1; } f = v[name]; //从prototype中获得函数 } else { //uber第一次调用 从prototype获得要执行的函数 f = p[name]; if (f == this[name]) { //如果函数属于当前prototype 则改为调用父对象的prototype f = v[name]; } } d[name] += 1; //记录我们在继承堆栈中所在位置 //使用除第一个以外所有的arguments 调用函数 第一个参数是执行的匿名函数名 r = f.apply(this, Array.prototype.slice.apply(arguments, [1])); d[name] -= 1; //恢复继承堆栈 return r; }); return this; }); //只继承父对象特定的函数。而非使用new parent()的继承的所有函数 Function.method("swiss", function (parent) { for (var i = 1; i < arguments.length; i++) { var name = arguments[i]; this.prototype[name] = parent[name]; } return this; }); /* Function.prototype.method 它提供了一个简单的方法,把函数于构造函数原型关联起来。 之所以有效,是因为所有的构造函数本身都是函数,所以能获得method这个新方法 Function.prototype.inherits这一函数可以用于提供简单的对象继承,它的代码主要围绕任意对象方法中调用 this.uber(methodname)为中心,并在让这个uber方法执行它要覆盖的父对象的方法。 Function.prototype.swiss这是.method函数的增强版,可以用于单一父对象获取多个函数。如果有多个父对象上 就能获得可用的多对象继承 */
调用代码:
function Person(name) { this.name = name; } Person.method("getName", function () { return this.name; }); function User(name, password) { this.name = name; this.password = password; } User.inherits(Person); User.method("getPassword", function () { return this.password; }); User.method("getName", function () { return "My name is :" + this.uber("getName"); }); var p = new Person("123"); alert(p.getName()); var u = new User("abc", "456"); alert(u.getPassword()); alert(u.getName());
第二个工具函数是base库
代码:
/*
Base.js, version 1.1a
Copyright 2006-2010, Dean Edwards
License: http://www.opensource.org/licenses/mit-license.php */
var Base = function() {
// dummy
};
Base.extend = function(_instance, _static) { // subclass
var extend = Base.prototype.extend;
// build the prototype
Base._prototyping = true;
var proto = new this;
extend.call(proto, _instance);
proto.base = function() {
// call this method from any other method to invoke that method's ancestor
};
delete Base._prototyping;
// create the wrapper for the constructor function
//var constructor = proto.constructor.valueOf(); //-dean
var constructor = proto.constructor;
var klass = proto.constructor = function() {
if (!Base._prototyping) {
if (this._constructing || this.constructor == klass) { // instantiation
this._constructing = true;
constructor.apply(this, arguments);
delete this._constructing;
} else if (arguments[0] != null) { // casting
return (arguments[0].extend || extend).call(arguments[0], proto);
}
}
};
// build the class interface
klass.ancestor = this;
klass.extend = this.extend;
klass.forEach = this.forEach;
klass.implement = this.implement;
klass.prototype = proto;
klass.toString = this.toString;
klass.valueOf = function(type) {
//return (type == "object") ? klass : constructor; //-dean
return (type == "object") ? klass : constructor.valueOf();
};
extend.call(klass, _static);
// class initialisation
if (typeof klass.init == "function") klass.init();
return klass;
};
Base.prototype = {
extend: function(source, value) {
if (arguments.length > 1) { // extending with a name/value pair
var ancestor = this[source];
if (ancestor && (typeof value == "function") && // overriding a method?
// the valueOf() comparison is to avoid circular references
(!ancestor.valueOf || ancestor.valueOf() != value.valueOf()) &&
/\bbase\b/.test(value)) {
// get the underlying method
var method = value.valueOf();
// override
value = function() {
var previous = this.base || Base.prototype.base;
this.base = ancestor;
var returnValue = method.apply(this, arguments);
this.base = previous;
return returnValue;
};
// point to the underlying method
value.valueOf = function(type) {
return (type == "object") ? value : method;
};
value.toString = Base.toString;
}
this[source] = value;
} else if (source) { // extending with an object literal
var extend = Base.prototype.extend;
// if this object has a customised extend method then use it
if (!Base._prototyping && typeof this != "function") {
extend = this.extend || extend;
}
var proto = {toSource: null};
// do the "toString" and other methods manually
var hidden = ["constructor", "toString", "valueOf"];
// if we are prototyping then include the constructor
var i = Base._prototyping ? 0 : 1;
while (key = hidden[i++]) {
if (source[key] != proto[key]) {
extend.call(this, key, source[key]);
}
}
// copy each of the source object's properties to this object
for (var key in source) {
if (!proto[key]) extend.call(this, key, source[key]);
}
}
return this;
}
};
// initialise
Base = Base.extend({
constructor: function() {
this.extend(arguments[0]);
}
}, {
ancestor: Object,
version: "1.1",
forEach: function(object, block, context) {
for (var key in object) {
if (this.prototype[key] === undefined) {
block.call(context, object[key], key, object);
}
}
},
implement: function() {
for (var i = 0; i < arguments.length; i++) {
if (typeof arguments[i] == "function") {
// if it's a function, call it
arguments[i](this.prototype);
} else {
// add the interface using the extend method
this.prototype.extend(arguments[i]);
}
}
return this;
},
toString: function() {
return String(this.valueOf());
}
});
调用代码:
var Person = Base.extend({
constructor: function (name) { this.name = name; },
getName: function () { return this.name; }
});
var User = Person.extend({
constructor: function (name, password) {
this.base(name);
this.password = password;
},
getPassWord: function () { return this.password; }
});
var p = new Person("123");
alert(p.getName());
var u = new User("456", "abc");
alert(u.getName());
alert(u.getPassWord());
有关base的详细介绍:http://dean.edwards.name/weblog/2006/03/base/
相关文章推荐
- JavaScript继承的一些工具函数
- javascript继承之工具函数一
- javascript继承之工具函数二
- javascript继承工具函数之三
- 原生Javascript写的一些常用的工具函数
- js创建对象 对象如何继承 及一些工具函数
- 【转】JavaScript中的对象、函数和继承
- jquery 刷新页面方法和一些javascript基础函数
- javascript中的setTimeout函数有一些独特的性质,很容易让人产生误解。下面就分别来讲述一下。
- 一些JavaScript时间处理函数整理
- Javascript面向对象编程(三):非函数对象的继承
- 常见javascript 兼容工具函数封装
- 收集的一些原生Js工具函数
- javascript工具函数
- 个人总结的一些JavaScript技巧、实用函数、简洁方法、编程细节
- 谈一谈javaScript中的一些常用函数
- javascript 一些关于css操作的函数
- javascript的函数、创建对象、封装、属性和方法、继承
- JavaScript常用工具和函数
- JQuery操作Javascript对象和数组的工具函数总览