javascript链式调用实现方式总结
方法链一般适合对一个对象进行连续操作(集中在一句代码)。一定程度上可以减少代码量,缺点是它占用了函数的返回值。
一、方法体内返回对象实例自身(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).method3(3); // obj -> prop1=1,prop2=2,prop3=3
可以看到对obj进行了连续三次操作,只要愿意ClassA的N多方法都这样定义,调用链会一直延续。
该方式缺点是链方法唯一地绑定于一种对象类型(ClaaaA),按这种方式实现链式操作,每定义一个类,其方法体中都要返回this。第二种方式可以解决这个问题。
二、对象传入后每次调用返回函数自身
/**
* chain 最易读版
* @param {Object} obj
*/ function singleChain1(obj){
function chain(){
if (arguments.length == 0){
return chain.obj;
}
var methodName = arguments[0], methodArgs = [].slice.call(arguments,1);
chain.obj[methodName].apply(chain.obj,methodArgs);
return chain;
}
chain.obj = obj;
return chain;
}
/**
* chain 易读版
* @param {Object} obj
*/
function singleChain2(obj){
return function(){
var Self = arguments.callee; Self.obj = obj;
if(arguments.length==0){
return Self.obj;
}
var methodName = arguments[0], methodArgs = [].slice.call(arguments,1);
Self.obj[methodName].apply(Self.obj,methodArgs);
return Self;
}
}
/**
* chain 精简版
* @param {Object} obj
*/
function singleChain3(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;
}
}
使用:
/**
* 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,且可以对任何对象进行链式调用。
接下来介绍YUI中Node类实现的链式调用方法。
在YUI3中,Node类的基础是Dom,很多Node类的方法都是调用Dom类的同名方法,如上面提到的setAttribute、setStyle等,
在Dom类源码中也未设置返回本对象,在Node类提供了importMethods方法来导入Dom中相同的方法并支持链式调用。示例代码如下:
//Dom类及静态方法
function Dom(id){
this.dom = document.getElementById(id);
} Dom.setStyle = function(node,name,value){
node.dom.style[name] = value;
} Dom.setAttribute = function(node,name,v){
node.dom.setAttribute(name,v);
} //Node类
function Node(id){
this.dom = document.getElementById(id);
} //添加方法的函数
Node.addMethod = function(method,fn){//,context Node.prototype[method] = function(){
var me = this;
//Array.prototype.unshift.call(arguments,me);
//or
arguments = Array.prototype.slice.call(arguments);
arguments.unshift(me);
fn.apply(me,arguments);
return me;
} } //批量添加方法的函数
Node.importMethods = function(host,methods){
for(var i in methods){
var m = methods[i];
var fn = host[m];
Node.addMethod(m,fn);
}
} //定义需要给Node类添加的方法名 列表
var methods = ['setStyle','setAttribute']; //使用批量添加方法的函数将Dom中的相关方法添加到Node中
Node.importMethods(Dom,methods); //可以在Node中进行链式调用
var n = new Node('log').setStyle('border','2px solid red').setAttribute('t',22);
在实际使用中,可以对原有的对象方法(如Dom中的方法)扩展到另一个类中(如Node类),在Node类中进行链式调用。当然也可以使用同样的方式(importMethods)不扩展而是覆盖Dom中的方法。
转自:http://houfeng0923.iteye.com/blog/1139525
javascript链式调用实现方式总结的更多相关文章
- javascript 链式调用+构造函数
前几天面试,有一个问题是使用构造函数实现链式调用,后面查看了一些简单的资料,整理一下 首先,先说一下JS 中构造函数和普通函数的区别,主要分为以下几点 1.构造函数也是一个普通函数,创建方式和普通函数 ...
- Javascript链式调用案例
jQuery用的就是链式调用.像一条连接一样调用方法. 链式调用的核心就是return this;,每个方法都返回对象本身. 下面是简单的模拟jQuery的代码, <script> win ...
- 一种javascript链式多重继承的方式(__proto__原型链)
var a=function(){this.foo='bar';} a.prototype={b:1}; var aa=function(){} aa.prototype={c:2,__proto__ ...
- js链式调用 柯里化
var d = 1; d.add(2).add(3).add(4) //输出10 写出这个add函数 Number.prototype.add = function(x){ return this + ...
- JavaScript动态加载script方式引用百度地图API 拓展---JavaScript的Promise
上一篇博客JavaScript动态加载script方式引用百度地图API,Uncaught ReferenceError: BMap is not defined 这篇文章中我接触到一个新的单词:Pr ...
- javascript方法链式调用和构造函数链式调用对比
先说一下方法链:B的实例从A继承了A中的同名方法,如果B的方法重载了A中的方法,B中的重载方法可能会调用A中的重载方法,这种方法称为方法链. 构造函数链:子类的构造函数B()有时需要调用父类的构造函数 ...
- Android 异步链式调用设计
本文讨论一下异步链式调用的设计与实现. 考虑如下情况: 情况1: 访问网络(或其他耗时的事情).通常的做法是: 1.显示一个ProgressDialog对话框,提示用户. 2.启动工作线程来执行耗时操 ...
- Scala 深入浅出实战经典 第51讲:Scala中链式调用风格的实现代码实战及其在Spark中应用
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- JavaScript 链式结构序列化详解
一.概述 在JavaScript中,链式模式代码,太多太多,如下: if_else: if(...){ //TODO }else if(...){ //TODO }else{ //TODO } swi ...
随机推荐
- RHEL 7.0 修改防火墙配置
RHEL 7.0默认使用的是firewall作为防火墙,这里改为iptables防火墙. 关闭firewall: systemctl stop firewalld.service #停止firewal ...
- Eclipse使用git最简易流程
git有诸多好处,网上都说的很清楚了,在这里我不再赘述.对于我来说,私下里想做一些项目,而又不能很好的保存自己的代码和进行版本控制,这时候,就用到了git.下面,就以我个人为例讲讲git从0开始如何安 ...
- 十、装饰(Decorator)模式 --结构模式(Structural Pattern)
装饰(Decorator)模式又名包装(Wrapper)模式[GOF95].装饰模式以对客户端透明的方 式扩展对象的功能,是继承关系的一个替代方案. 装饰模式类图: 类图说明: 抽象构件(Compon ...
- CSS开发经验
1.尽量用class来定义样式.尽量少使用 .div1 ul li{}这样的样式下去,因为如果li里面还有<div><ul><li>这些元素的话会造成干扰,应该给 ...
- jQuery中的选择器《思维导图》
学习jQuery的课程中,我对jQuery中的选择器有了更深的认识,它的简洁写法,完美的兼容性,可靠的处理机制,都让我们省了很多事, 下面是我在学习过程中对jQuery选择器写的思维导图(全屏查看:& ...
- XML文档形式&JAVA抽象类和接口的区别&拦截器过滤器区别
XML文档定义有几种形式?它们之间有何本质区别?解析XML文档有哪几种方式? a: 两种形式 dtd schemab: 本质区别:schema本身是xml的,可以被XML解析器解析(这也是从DTD上发 ...
- Path Sum II 解答
Question Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the ...
- HDU 3308 LCIS(线段树单点更新区间合并)
LCIS Given n integers. You have two operations: U A B: replace the Ath number by B. (index counting ...
- UML_活动图
一.活动图的组成元素 Activity Diagram Element 1.活动状态图(Activity) 2.动作状态(Actions) 3.动作状态约束(Action Constraints) 4 ...
- python手记(44)
#!/usr/bin/env python # -*- coding: utf-8 -*- #http://blog.csdn.net/myhaspl #code:myhaspl@qq.com imp ...