JS链式调用的实现方法


Posted in Javascript onMarch 07, 2013

链式调用
    链式调用其实只不过是一种语法招数。它能让你通过重用一个初始操作来达到用少量代码表达复杂操作的目的。该技术包括两个部分:

一个创建代表HTML元素的对象的工厂。

一批对这个HTML元素执行某些操作的方法。

调用链的结构
$函数负责创建支持链式调用的对象

(function() {
    /*
     * 创建一个私有class
     * @param {Object} els  arguments 所有参数组成的类数组
     */
    function _$(els) {
        this.elements = [];             //存放HTML元素
        for(var i=0, len=els.length; i<len; i++) {
            var element = els[i];
            if(typeof element === 'string') {
                element = document.getElementById(element);
            }
            this.elements.push(element);
        }
    }
    //对HTML元素可执行的操作
    _$.prototype = {
        each: function() {},
        setStyle: function() {},
        show: function() {},
        addEvent: function() {},
    };    
    //对外开放的接口
    window.$ = function() {
        return new _$(arguments);
    };   
})();

由于所有对象都会继承其原型对象的属性和方法,所以我们可以让定义在原型对象中的那些方法都返回用以调用方法的实例对象的引用,这样就可以对那些方法进行链式调用了。

(function() {
    /*
     * 创建一个私有class
     * @param {Object} els  arguments 所有参数组成的类数组
     */
    function _$(els) {
        //...
    }
    //对HTML元素可执行的操作
    _$.prototype = {
        each: function(fn) {        //fn 回调函数
            for(var i=0; i<this.elements.length; i++) {
                //执行len次,每次把一个元素elements[i]作为参数传递过去
                fn.call(this, this.elements[i]);
            }
            return this;
        },
        setStyle: function(prop, value) {
            this.each(function(el) {
                el.style[prop] = value;
            });
            return this;
        },
        show: function() {
            var that = this;
            this.each(function(el) {
                that.setStyle('display', 'block');
            });
            return this;
        },
        addEvent: function(type, fn) {
            var addHandle = function(el) {
                if(document.addEventListener) {
                    el.addEventListener(type, fn, false);
                }else if(document.attachEvent) {
                    el.attachEvent('on'+type, fn);
                }
            };
            this.each(function(el) {
                addHandle(el);
            });
            return this;  
        }
    };
    //对外开放的接口
    window.$ = function() {
        return new _$(arguments);
    }})();

//----------------------- test --------
$(window).addEvent('load', function() {
    $('test-1', 'test-2').show()
    .setStyle('color', 'red')
    .addEvent('click', function() {
        $(this).setStyle('color', 'green');
    });
})

链式调用的方法获取数据
    使用回调函数从支持链式调用的方法获取数据。链式调用很适合赋值器方法,但对于取值器方法,你可能希望他们返回你要的数据而不是this(调用该方法的对象).解决方案:利用回调技术返回所要的数据.

window.API = window.API || function() {
    var name = 'mackxu';
    //特权方法
    this.setName = function(name0) {
        name = name0;
        return this;
    };
    this.getName = function(callback) {
        callback.call(this, name);
        return this;
    };
};
//------------- test ---
var obj = new API();
obj.getName(console.log).setName('zhangsan').getName(console.log);

设计一个支持方法链式调用的JS库
JS库特征:

事件: 添加和删除事件监听器、对事件对象进行规划化处理

DOM: 类名管理、样式管理

Ajax: 对XMLHttpRequest进行规范化处理

Function.prototype.method = function(name, fn) {
    this.prototype[name] = fn;
    return this;
};
(function() {
    function _$(els) {
        //...
    }
    /*
     * Events
     *      addEvent
     *      removeEvent
     */
    _$.method('addEvent', function(type, fn) {
        //...  
    }).method('removeEvent', function(type, fn) {    })
    /*
     * DOM
     *      addClass
     *      removeClass
     *      hover
     *      hasClass
     *      getClass
     *      getStyle
     *      setStyle
     */
    .method('addClass', function(classname) {
        //...
    }).method('removeClass', function(classname) {
        //...
    }).method('hover', function(newclass, oldclass) {
        //...
    }).method('hasClass', function(classname) {
        //...
    }).method('getClass', function(classname) {
        //...
    }).method('getStyle', function(prop) {
        //...
    }).method('setStyle', function(prop, val) {
        //...
    })
    /*
     * AJAX
     *      ajax
     */
    .method('ajax', function(url, method) {
        //...
    });
    window.$ = function() {
        return new _$(arguments);
    };
    //解决JS库命名冲突问题
    window.installHelper = function(scope, interface) {
        scope[interface] = function() {
            return _$(arguments)
        }
    }  
})();

小结:

    链式调用有助于简化代码的编写工作,并在某种程度上可以让代码更加简洁、易读。很多时候使用链式调用可以避免多次重复使用一个对象变量,从而减少代码量。如果想让类的接口保持一致,让赋值器和取值器都支持链式调用,那么你可以在取值器中使用回调函数来解决获取数据问题。

Javascript 相关文章推荐
使用Jquery打造最佳用户体验的登录页面的实现代码
Jul 08 Javascript
判断一个对象是否为jquery对象的方法
Mar 12 Javascript
jQuery实现当前页面标签高亮显示的方法
Mar 10 Javascript
Node.js中的流(Stream)介绍
Mar 30 Javascript
JS 全屏和退出全屏详解及实例代码
Nov 07 Javascript
Angualrjs和bootstrap相结合实现数据表格table
Mar 30 Javascript
ExtJs的Ext.Ajax.request实现waitMsg等待提示效果
Jun 14 Javascript
基于JavaScript实现表格滚动分页
Nov 22 Javascript
vue中本地静态图片路径写法
Mar 06 Javascript
基于JS实现数字动态变化显示效果附源码
Jul 18 Javascript
Vue中qs插件的使用详解
Feb 07 Javascript
JavaScript HTML DOM 元素 (节点)新增,编辑,删除操作实例分析
Mar 02 Javascript
jQuery滚动加载图片效果的实现
Mar 06 #Javascript
HTML上传控件取消选择
Mar 06 #Javascript
jQuery操作Select选择的Text和Value(获取/设置/添加/删除)
Mar 06 #Javascript
JQuery操作tr和td内容的方法实例
Mar 06 #Javascript
node在两个div之间移动,用ztree实现
Mar 06 #Javascript
js实现一个省市区三级联动选择框代码分享
Mar 06 #Javascript
自己写了一个展开和收起的多更能型的js效果
Mar 05 #Javascript
You might like
smarty的保留变量问题
2008/10/23 PHP
PHP中的按位与和按位或操作示例
2014/01/27 PHP
php使用多个进程同时控制文件读写示例
2014/02/28 PHP
php+xml编程之xpath的应用实例
2015/01/24 PHP
详解php与ethereum客户端交互
2018/04/28 PHP
php实现微信支付之现金红包
2018/05/30 PHP
thinkphp5.1 框架钩子和行为用法实例分析
2020/05/25 PHP
Javascript String对象扩展HTML编码和解码的方法
2009/06/02 Javascript
js动态添加事件并可传参数示例代码
2013/10/21 Javascript
在JavaScript中使用开平方根的sqrt()方法
2015/06/15 Javascript
JQuery validate插件验证用户注册信息
2016/05/11 Javascript
微信小程序开发之animation循环动画实现的让云朵飘效果
2017/07/14 Javascript
Django+Vue.js搭建前后端分离项目的示例
2017/08/07 Javascript
全站最详细的Vuex教程
2018/04/13 Javascript
Vue数据双向绑定底层实现原理
2019/11/22 Javascript
如何使用Javascript中的this关键字
2020/05/28 Javascript
一篇文章入门Python生态系统(Python新手入门指导)
2015/12/11 Python
详解Python中类的定义与使用
2017/04/11 Python
python调用百度地图WEB服务API获取地点对应坐标值
2019/01/16 Python
Python3.5多进程原理与用法实例分析
2019/04/05 Python
解决pyinstaller打包发布后的exe文件打开控制台闪退的问题
2019/06/21 Python
python中count函数简单用法
2020/01/05 Python
Python对象的属性访问过程详解
2020/03/05 Python
对python中return与yield的区别详解
2020/03/12 Python
python Socket网络编程实现C/S模式和P2P
2020/06/22 Python
详解使用双缓存解决Canvas clearRect引起的闪屏问题
2019/04/29 HTML / CSS
英国最大的LED专业零售商:Led Hut
2018/03/16 全球购物
HashMap和Hashtable的区别
2013/05/18 面试题
计算机维护专业推荐信
2014/02/27 职场文书
化学专业自荐信
2014/05/28 职场文书
防汛工作情况汇报
2014/10/28 职场文书
优秀教师先进材料
2014/12/16 职场文书
2014年学生党支部工作总结
2014/12/20 职场文书
2015秋学期开学寄语
2015/05/28 职场文书
《给予树》教学反思
2016/03/03 职场文书
nodejs利用readline提示输入内容实例代码
2021/07/15 NodeJs