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 ...
随机推荐
- "windows 正在启动"
xp 在cmd下使用了control userpasswords2 设定开机不需要密码之后,开机停留在“window正在启动”,无法进入.估计是设置的时候密码输入错误了( 并不会提示你错误:() 在停 ...
- USB Mass Storage学习笔记-STM32+FLASH实现U盘
一.内容概述 采用STM32内部自带USB控制器外加大页NAND FLASH K9F1G08U0A实现一个128M的U盘. 1.STM32的USB控制器 STM32F103的MCU自带USB从控制器 ...
- Struts2+Spring+Ibatis集成合并
上一篇博客讲述了Struts2+Spring的集成合并,主要是利用了一个中间jar包,这篇博客在加上Ibatis持久层框架,三个框架进行合并.其中Struts2和Spring部分和前边的一样,主要是讲 ...
- Struts2(三)——数据在框架中的数据流转问题
一款软件,无在乎对数据的处理.而B/S软件,一般都是用户通过浏览器客户端输入数据,传递到服务器,服务器进行相关处理,然后返回到指定的页面,进行相关显示,完成相关功能.这篇博客重点简述一下Struts2 ...
- strcpy与memcpy的区别
strcpy和memcpy的区别 strcpy和memcpy都是标准C库函数,它们有下面的特点. strcpy提供了字符串的复制.即strcpy只用于字符串复制,并且它不仅复制字符串内容之外,还会复制 ...
- ubuntu WiFi: operation not possible due to RF-kill《转载》
Some people have been experiencing WiFi problems with Ubuntu 10.10 since an update that happend just ...
- 搭建高可用mongodb集群—— 分片
从节点每个上面的数据都是对数据库全量拷贝,从节点压力会不会过大? 数据压力大到机器支撑不了的时候能否做到自动扩展? 在系统早期,数据量还小的时候不会引起太大的问题,但是随着数据量持续增多,后续迟早会出 ...
- DataSet、DataTable、DataRow区别
DataSet 表示数据在内存中的缓存. 属性 Tables 获取包含在 DataSet 中的表的集合. ds.Tables["sjxx"] DataTable 表示内存中数据 ...
- Java编程的23种设计模式
设计模式(Design Patterns) --可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用. ...
- C#抓取网页内容
学习材料一 <C#抓取网页数据分析> 抓取Web网页数据分析 HttpWebRequest 和 HttpWebResponse 的应用