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 相关文章推荐
JS代码格式化和语法着色V2
Oct 14 Javascript
ExtJS PropertyGrid中使用Combobox选择值问题
Jun 13 Javascript
浅谈关于JavaScript的语言特性分析
Apr 11 Javascript
js函数在frame中的相互调用详解
Mar 03 Javascript
javascript制作的网页侧边弹出框思路及实现代码
May 21 Javascript
JS获取及验证开始结束日期的方法
Aug 20 Javascript
Angular2 环境配置详细介绍
Sep 21 Javascript
详解使用fetch发送post请求时的参数处理
Apr 05 Javascript
JS实现div模块的截图并下载功能
Oct 17 Javascript
vue中filters 传入两个参数 / 使用两个filters的实现方法
Jul 15 Javascript
vue学习之Vue-Router用法实例分析
Jan 06 Javascript
vue css 引入asstes中的图片无法显示的四种解决方法
Mar 16 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
解析yahoo邮件用phpmailer发送的实例
2013/06/24 PHP
php下foreach提示Warning:Invalid argument supplied for foreach()的解决方法
2014/11/11 PHP
PHP对象链式操作实现原理分析
2016/10/09 PHP
PHP分页显示的方法分析【附PHP通用分页类】
2018/05/10 PHP
JAVASCRIPT  THIS详解 面向对象
2009/03/25 Javascript
jQueryUI写一个调整分类的拖放效果实现代码
2012/05/10 Javascript
JavaScript中为什么null==0为false而null大于=0为true(个人研究)
2013/09/16 Javascript
node.js中使用q.js实现api的promise化
2014/09/17 Javascript
JavaScript实现网页对象拖放功能的方法
2015/04/15 Javascript
jQuery检测某个元素是否存在代码分享
2015/07/09 Javascript
jqueryMobile 动态添加元素,展示刷新视图的实现方法
2016/05/28 Javascript
JS使用正则表达式实现关键字替换加粗功能示例
2016/08/03 Javascript
javascript跨域请求包装函数与用法示例
2016/11/03 Javascript
jquery网页日历显示控件calendar3.1使用详解
2016/11/24 Javascript
Angular.js指令学习中一些重要属性的用法教程
2017/05/24 Javascript
JavaScript实现的DOM绘制柱状图效果示例
2018/08/08 Javascript
koa2服务端使用jwt进行鉴权及路由权限分发的流程分析
2019/07/22 Javascript
layer扩展打开/关闭动画的方法
2019/09/23 Javascript
vue表单中遍历表单操作按钮的显示隐藏示例
2019/10/30 Javascript
一看就会的vuex实现登录验证(附案例)
2020/01/09 Javascript
jQuery实现二级导航菜单的示例
2020/09/30 jQuery
vue中可编辑树状表格的实现代码
2020/10/31 Javascript
NodeJS配置CORS实现过程详解
2020/12/02 NodeJs
python实现的二叉树定义与遍历算法实例
2017/06/30 Python
Python实现将HTML转换成doc格式文件的方法示例
2017/11/20 Python
python基础教程项目五之虚拟茶话会
2018/04/02 Python
python web自制框架之接受url传递过来的参数实例
2018/12/17 Python
Python实现连接MySql数据库及增删改查操作详解
2019/04/16 Python
python 梯度法求解函数极值的实例
2019/07/10 Python
Django处理Ajax发送的Get请求代码详解
2019/07/29 Python
Python如何定义有可选参数的元类
2020/07/31 Python
MyFrenchPharma中文网:最大的法国药妆平台
2016/10/07 全球购物
一些Unix笔试题和面试题
2012/09/25 面试题
应届生找工作求职信
2014/06/24 职场文书
广告业务员岗位职责
2015/02/13 职场文书
庆七一晚会主持词
2015/06/30 职场文书