相对于函数式语言利用返回值不断创建新对象堆叠而成的复杂结构
对象语言的方法链则是针对单一对象进行连续操作的首选方法之一
但有些时候,它的缺陷也是明显的……
为了调用链方法,必须显式地将方法挂为对象的成员;
而为了形成方法链,链方法必须专门被设计成返回对象自身
这样的结构使方法链严格依赖于对象类,从而限制了链方法作为独立工具包存在的可能性
好主意仍然来自于 jquery。
通过使用一个方法而不是一个类对操作对象进行轻量的包装
我们可以直接用对象之外的静态方法形成方法链
所要做的只是保证让操作对象成为链方法的第一个参数:
var setA = function (obj, a) { obj.a = a; };
var setB = function (obj, b) { obj.b = b; };
var sumA = function (obj) { obj.a = obj.a + obj.b; };
var subB = function (obj) { obj.b = obj.a - obj.b; };
var swap = function (obj) { var t = obj.a; obj.a = obj.b; obj.b = t; };
var obj = { a : null, b : null };
$chain(obj)(setA, 1)(setB, 2)(sumA)(subB)(swap);
alert(obj.a + ", " + obj.b); // 1, 3
对值类型的操作则相对麻烦一些……
由于无法通过引用修改原对象,链方法仍然需要返回运算结果:
(注:操作对象不是值类型的话,链方法的返回值将被丢弃)
var trim =
function (str) {
return str.replace(/^\s+/, "").replace(/\s+$/, ""); };
var replace =
function (str, regexp, newSubStr) {
return str.replace(regexp, newSubStr); };
alert($chain(" ABCD ")(trim)(replace, /[B-C]/g, "#")()); // A##D
最后的无参数调用解开包装,并从方法链中取回对象
这使得方法链本身也可以作为参数嵌入到其它的方法调用中
附:包装方法 $chain:
var $chain = function () {
var isPrimitive =
function (obj) {
var t = (typeof obj);
return (obj === undefined || obj === null ||
t == "boolean" || obj instanceof Boolean ||
t == "number" || obj instanceof Number ||
t == "string" || obj instanceof String); };
var link =
function (chain, arguments) {
if (arguments.length === 0) {
return chain.pendant; }
var proc = arguments[0];
var args = [chain.pendant];
for (var i=1; i<arguments.length; i++) {
args.push(arguments[i]); }
var ret = proc.apply(this, args);
if (isPrimitive(chain.pendant)) {
chain.pendant = ret; }
return chain; };
var $chain =
function (obj) {
var chain = function () { return link(chain, arguments); };
chain.pendant = obj;
return chain; };
return $chain; } ();
--
修改:withinsea FROM 221.221.163.26
FROM 221.221.163.26