- 主题:[js] 静态方法链
相对于函数式语言利用返回值不断创建新对象堆叠而成的复杂结构
对象语言的方法链则是针对单一对象进行连续操作的首选方法之一
但有些时候,它的缺陷也是明显的……
为了调用链方法,必须显式地将方法挂为对象的成员;
而为了形成方法链,链方法必须专门被设计成返回对象自身
这样的结构使方法链严格依赖于对象类,从而限制了链方法作为独立工具包存在的可能性
好主意仍然来自于 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
orz
【 在 withinsea (沐海~魔導奏器|歌の琴フォルテール) 的大作中提到: 】
: 相对于函数式语言利用返回值不断创建新对象堆叠而成的复杂结构
: 对象语言的方法链则是针对单一对象进行连续操作的首选方法之一
: 但有些时候,它的缺陷也是明显的……
: ...................
--
FROM 221.218.129.*
空门大师后继有人了!
【 在 withinsea (沐海~魔導奏器|歌の琴フォルテール) 的大作中提到: 】
: 相对于函数式语言利用返回值不断创建新对象堆叠而成的复杂结构
: 对象语言的方法链则是针对单一对象进行连续操作的首选方法之一
: 但有些时候,它的缺陷也是明显的……
: ...................
--
FROM 211.99.222.*
不是zeze了?^^
【 在 kabbesy (Arthas) 的大作中提到: 】
: orz
--
FROM 221.221.163.26
汗,岂敢……
【 在 pizzaxp (aka 世界上第二可爱的人) 的大作中提到: 】
: 空门大师后继有人了!
--
FROM 221.221.163.26
反正js忘光了
干脆orz
【 在 withinsea (沐海~魔導奏器|歌の琴フォルテール) 的大作中提到: 】
: 不是zeze了?^^
--
FROM 221.218.129.*
买蛋糕!
看起来好像走火入魔了。。。
但愿只是在做做练习而已
【 在 withinsea (沐海~魔導奏器|歌の琴フォルテール) 的大作中提到: 】
: 相对于函数式语言利用返回值不断创建新对象堆叠而成的复杂结构
: 对象语言的方法链则是针对单一对象进行连续操作的首选方法之一
: 但有些时候,它的缺陷也是明显的……
: ...................
--
FROM 222.76.228.*
我自己所有工具方法都不挂在類底下
這個東西對我來講很提高效率的
【 在 modico (modico) 的大作中提到: 】
: 买蛋糕!
: 看起来好像走火入魔了。。。
: 但愿只是在做做练习而已
: ...................
--
FROM 221.221.150.101
效率?
不过是少敲了几个字符。
也谈不上运行效率。
方法链的写法不利于调试,也就是不利于设断点,死的时候都不知道死在半道哪儿了。
不是个好习惯。
【 在 withinsea (沐海~魔導奏器|歌の琴フォルテール) 的大作中提到: 】
: 我自己所有工具方法都不挂在類底下
: 這個東西對我來講很提高效率的
--
FROM 222.76.228.*
你這完全只是不喜歡方法鏈嘛
而且誰說不能調試的……
這個丟給 firebug,斷得很好
var chain = $chain({ a : 0, b : 0 });
chain
(setA, 1)
(setB, 2)
(sumA)
(subB)
(swap);
【 在 modico (modico) 的大作中提到: 】
: 效率?
: 不过是少敲了几个字符。
: 也谈不上运行效率。
: 方法链的写法不利于调试,也就是不利于设断点,死的时候都不知道死在半道哪儿了。
: 不是个好习惯。
--
FROM 221.221.150.101