锁定老帖子 主题:JavaScript中链式调用之研习
该帖已经被评为新手帖
|
|
---|---|
作者 | 正文 |
发表时间:2010-08-27
最后修改:2011-04-06
方法链一般适合对一个对象进行连续操作(集中在一句代码)。一定程度上可以减少代码量,缺点是它占用了函数的返回值。
一、方法体内返回对象实例自身(this)function ClassA(){ this.prop1 = null; this.prop2 = null; this.prop3 = null; } ClassA.prototype = { method1 : function(p1){ this.prop1 = p1; return this; }, method2 : function(p2){ this.prop2 = p2; return this; }, method3 : function(p3){ this.prop3 = p3; return this; } }
定义了function/类ClassA。有三个属性/字段prop1,prop2,prop3,三个方法methed1,method2,method3分别设置prop1,prop2,prop3。 var obj = new ClassA(); obj.method1(1).method2(2).method(3); // obj -> prop1=1,prop2=2,prop3=3
可以看到对obj进行了连续三次操作,只要愿意ClassA的N多方法都这样定义,调用链会一直延续。
二、对象传入后每次调用返回函数自身/** * chain 精简版 * @param {Object} obj */ function chain(obj){ return function(){ var Self = arguments.callee; Self.obj = obj; if(arguments.length==0){ return Self.obj; } Self.obj[arguments[0]].apply(Self.obj,[].slice.call(arguments,1)); return Self; } } //定义的function/类ClassB function ClassB(){ this.prop1 = null; this.prop2 = null; this.prop3 = null; } ClassB.prototype = { method1 : function(p1){ this.prop1 = p1; }, method2 : function(p2){ this.prop2 = p2; }, method3 : function(p3){ this.prop3 = p3; } } 注意ClassB的method1,method2,method3中不再返回this了。
链式调用如下: var obj = new ClassB(); chain(obj)('method1',4)('method2',5)('method3',6); // obj -> prop1=4,prop2=5,prop3=6
第一种方式3次调用后返回了对象自身,这里使用一个空"()"取回对象 // result -> prop1=4,prop2=5,prop3=6 var result = chain(obj)('method1',4)('method2',5)('method3',6)();
这种方式写类时方法体中无须返回this,且可以对任何对象进行链式调用。 obj .method1(arg1) .method2(arg2) .method3(arg3) ... chain(obj) (method1,arg1) (method2,arg2) (method3,arg3) ...
最后,感谢沐海,我是从wee库中获取以上灵感的。
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-08-27
呵呵,事实上只要理解了函数调用就是一个表达式,就好理解了
对于高阶函数式编程,执行函数后返回另一个函数(或其自身)是很常见的 |
|
返回顶楼 | |
发表时间:2010-08-27
最后修改:2010-08-27
zhouyrt 写道
二、对象传入后每次调用返回函数自身
/** * chain 精简版 * @param {Object} obj */ function chain(obj){ return function(){ var Self = arguments.callee; Self.obj = obj; if(arguments.length==0){ return Self.obj; } Self.obj[arguments[0]].apply(Self.obj,[].slice.call(arguments,1)); return Self; } }
第二种方式还是第一次见,很巧妙的用法
不过可以简化一下,不使用callee,直接利用闭包: function chain(obj){ var fn = function(method){ if(arguments.length <= 0){ return fn; } var args = Array.prototype.slice.call(arguments, 1); obj[method].apply(obj, args); return fn; } return fn; } PS:那个[].slice的用法还真是。。。够短,不过总觉得凭白无故创建一个数组只为借它的一个方法用用,有点…… |
|
返回顶楼 | |
发表时间:2010-08-27
最后修改:2010-08-27
使用起来能更舒服就好了
例如 var result = chain(obj).method1(4).method2(5).method3(6); 要实现估计要对obj的方法进行重构 还要判断方法本身有没有return |
|
返回顶楼 | |
发表时间:2010-08-27
cloudgamer 写道 使用起来能更舒服就好了
例如 var result = chain(obj).method1(4).method2(5).method3(6); 要实现估计要对obj的方法进行重构 还要判断方法本身有没有return 谢. |
|
返回顶楼 | |
发表时间:2010-08-27
第一个还好理解,第二个Self.obj[arguments[0]].apply(Self.obj,[].slice.call(arguments,1)); 这句直接看晕了。
|
|
返回顶楼 | |
发表时间:2010-08-28
我在第二种方式上解理起来.....表示压力很大。
我经常用的是第一种。 |
|
返回顶楼 | |
发表时间:2010-08-28
To: clue,tangjikey,ccyingfu
附件中有“易读版”,“最易读版”的chain。 |
|
返回顶楼 | |
发表时间:2010-08-28
这个……理解上有难度。。
|
|
返回顶楼 | |
发表时间:2010-08-30
以前写个一个invoke方法,很是类似于第二个方法,只是一个返回的运算结果,而一个是调用对象callee。
楼主方法在链式调用功能更强大,更适合于无返回参数的运算 |
|
返回顶楼 | |