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实现按钮加背景图片常用方法
Nov 01 Javascript
jquery插件EasyUI中form表单提交实例分享
Jan 11 Javascript
node.js cookie-parser 中间件介绍
Jun 06 Javascript
微信小程序简单实现form表单获取输入数据功能示例
Nov 30 Javascript
微信小程序loading组件显示载入动画用法示例【附源码下载】
Dec 09 Javascript
详解vue-element Tree树形控件填坑路
Mar 26 Javascript
详解将微信小程序接口Promise化并使用async函数
Aug 05 Javascript
微信小程序转发事件实现解析
Oct 22 Javascript
ES2020 新特性(种草)
Jan 12 Javascript
使用vue打包进行云服务器上传的问题
Mar 02 Javascript
vue axios请求成功却进入catch的原因分析
Sep 08 Javascript
vue+iview实现分页及查询功能
Nov 17 Vue.js
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
深入理解用mysql_fetch_row()以数组的形式返回查询结果
2013/06/05 PHP
Laravel框架路由和控制器的绑定操作方法
2018/06/12 PHP
PHP中用Trait封装单例模式的实现
2019/12/18 PHP
屏蔽IE弹出&quot;您查看的网页正在试图关闭窗口,是否关闭此窗口&quot;的方法
2013/12/31 Javascript
php的文件上传入门教程(实例讲解)
2014/04/10 Javascript
jQuery插件jFade实现鼠标经过的图片高亮其它变暗
2015/03/14 Javascript
举例详解JavaScript中Promise的使用
2015/06/24 Javascript
javascript数组克隆简单实现方法
2015/12/16 Javascript
jquery跟随屏幕滚动效果的实现代码
2016/04/13 Javascript
JavaScript地理位置信息API
2016/06/11 Javascript
JS判断form内所有表单是否为空的简单实例
2016/09/09 Javascript
AngularJS变量及过滤器Filter用法分析
2016/11/22 Javascript
JS实现仿饿了么在浏览器标签页失去焦点时网页Title改变
2017/06/01 Javascript
vue2.0与bootstrap3实现列表分页效果
2017/11/28 Javascript
jQuery+SpringMVC中的复选框选择与传值实例
2018/01/08 jQuery
详解jQuery中的isPlainObject()使用方法
2018/02/27 jQuery
如何自动化部署项目?折腾服务器之旅~
2019/04/16 Javascript
node删除、复制文件或文件夹示例代码
2019/08/13 Javascript
vue3使用vue-count-to组件的实现
2020/12/25 Vue.js
python 定时修改数据库的示例代码
2018/04/08 Python
Python中面向对象你应该知道的一下知识
2019/07/10 Python
Python检查图片是否损坏及图片类型是否正确过程详解
2019/09/30 Python
从pandas一个单元格的字符串中提取字符串方式
2019/12/17 Python
python  ceiling divide 除法向上取整(或小数向上取整)的实例
2019/12/27 Python
python爬虫模拟浏览器访问-User-Agent过程解析
2019/12/28 Python
python调用HEG工具批量处理MODIS数据的方法及注意事项
2020/02/18 Python
python爬虫开发之Beautiful Soup模块从安装到详细使用方法与实例
2020/03/09 Python
中学教师管理制度
2014/01/14 职场文书
优秀求职信范文分享
2014/01/26 职场文书
大型营销活动计划书
2014/04/28 职场文书
皇城相府导游词
2015/02/06 职场文书
第28个世界无烟日活动总结
2015/02/10 职场文书
查看nginx配置文件路径和资源文件路径的方法
2021/03/31 Servers
css3实现背景图片颜色修改的多种方式
2021/04/13 HTML / CSS
Python入门学习之类的相关知识总结
2021/05/25 Python
Python Pandas常用函数方法总结
2021/06/15 Python