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网络游戏-(模拟城市webgame)提供的一些例子下载
Oct 14 Javascript
jquery 日期分离成年月日的代码
May 14 Javascript
javascript中的关于类型转换的性能优化
Dec 14 Javascript
简单方法判断JavaScript对象为null或者属性为空
Sep 26 Javascript
JavaScript中创建对象的7种模式详解
Feb 21 Javascript
vuejs2.0实现一个简单的分页示例
Feb 22 Javascript
jquery PrintArea 实现票据的套打功能(代码)
Mar 17 Javascript
JS+HTML5实现图片在线预览功能
Jul 22 Javascript
js中如何完美的解析数据
Mar 18 Javascript
Javascript中弹窗confirm与prompt的区别
Oct 26 Javascript
JS Array.from()将伪数组转换成数组的方法示例
Mar 23 Javascript
Element InputNumber 计数器的实现示例
Aug 03 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
浅谈PHP的$_SERVER[SERVER_NAME]
2017/02/04 PHP
php多文件打包下载的实例代码
2017/07/12 PHP
深入研究PHP中的preg_replace和代码执行
2018/08/15 PHP
JavaScript 编程引入命名空间的方法与代码
2007/08/13 Javascript
jQuery数据类型小结(14个)
2016/01/08 Javascript
详解Node.js如何开发命令行工具
2016/08/14 Javascript
JS组件系列之使用HTML标签的data属性初始化JS组件
2016/09/14 Javascript
原生JS实现自定义滚动条效果
2020/10/27 Javascript
Popup弹出框添加数据实现方法
2017/10/27 Javascript
基于Bootstrap表单验证功能
2017/11/17 Javascript
JS中Promise函数then的奥秘探究
2018/07/30 Javascript
简单了解vue 插值表达式Mustache
2020/07/22 Javascript
JavaScript实现多层颜色选项卡嵌套
2020/09/21 Javascript
利用python获得时间的实例说明
2013/03/25 Python
Python sys.path详细介绍
2013/10/17 Python
Python全局变量操作详解
2015/04/14 Python
Python简单检测文本类型的2种方法【基于文件头及cchardet库】
2016/09/18 Python
Python实现PS图像调整之对比度调整功能示例
2018/01/26 Python
python打印9宫格、25宫格等奇数格 满足横竖斜相加和相等
2019/07/19 Python
Python获取时间范围内日期列表和周列表的函数
2019/08/05 Python
python argparser的具体使用
2019/11/10 Python
浅谈PyQt5中异步刷新UI和Python多线程总结
2019/12/13 Python
Django DRF路由与扩展功能的实现
2020/06/03 Python
Python使用tkinter实现摇骰子小游戏功能的代码
2020/07/02 Python
Python如何把字典写入到CSV文件的方法示例
2020/08/23 Python
Python通过字典映射函数实现switch
2020/11/06 Python
快速创建 HTML5 Canvas 电信网络拓扑图的示例代码
2018/03/21 HTML / CSS
澳大利亚婴儿、幼儿和儿童在线设计师商店:Smooch Baby
2019/02/16 全球购物
大学生实习期自我评价范文
2013/10/03 职场文书
好的自荐信的要求
2013/10/30 职场文书
三方股东合作协议书范本
2014/09/28 职场文书
就业协议书盖章的注意事项
2014/09/28 职场文书
政府个人对照检查材料思想汇报
2014/10/08 职场文书
微信搭讪开场白
2015/05/28 职场文书
辞职报告(范文三篇)
2019/08/27 职场文书
Python Matplotlib绘制等高线图与渐变色扇形图
2022/04/14 Python