javascript链式调用的实现方式

简介:

本文从ITeye导入 

 

在我们所用到的库中,可以看到很多诸如

$(window).addEvent('load', function(){
    $('test').show().setStyle('color', 'red').addEvent('click', function(e){
        $(this).setStyle('color', 'yellow');
    });
});

 的链式调用,那么这样的链式结构是怎么实现的呢,下面我们利用代码来探讨一番:

 

 先分解下,我们队$函数已经很熟悉了,他通常返回一个HTML元素或者HTML元素的集合,如下所示:

function $(){
    var elements = [];
    for(var i = 0, len = arguments.length; i < len; i++){
        var element = els[i];
        if(typeof element === 'string'){
            element = document.getElementById(element);
        }
        elements.push(element);
    }
    return elements;
}

 但是,如果把这个函数改造为一个构造器,把那些元素作为数组保存在一个实例属性中,并让所有定义在构造器函数的prototype属性所指对象中的方法都返回用以调用放方法的那个实例的引用,那么他就具有了进行链式调用的能力。

 

先别说的太远,我们首先需要把这个$函数改为一个工厂函数,他负责创建支持链式调用的对象。

(function(){

    function _$(els){
        this.element = [];
        for(var i = 0, len = els.length; i < len; i++){
            var element = els[i];
            if(typeof element === 'string'){
                element = document.getElementById(element);
            }
            this.element.push(element);
        }
        return this;
    }
    window.$ = function(){
        return new _$(arguments);
    }
})();       

由于所有对象都会继承其原型对象的属性和方法,所以我们可以让定义原型对象中的那几个方法都返回用以调用方法的实例对象的引用,这样既可以对那些方法进行链式调用,想好这一点,我们现在就动手在_$这个私用构造函数的prototype对象那个中添加方法,以便实现链式调用。

 

(function(){

    function _$(els){
        this.element = [];
        for(var i = 0, len = els.length; i < len; i++){
            var element = els[i];
            if(typeof element === 'string'){
                element = document.getElementById(element);
            }
            this.element.push(element);
        }
        return this;
    }

    _$.prototype = {
        each: function(fn){
            for(var i = 0, len = this.element.length; i < len; i++){
                fn.call(this, this.element[i]);
            }
            return this;
        },

        setStyle: function(prop, val){
            this.each(function(el){
                el.style[prop] = val;
            });
            return this;
        },

        show: function(){
            var that = this;
            this.each(function(el){
                that.setStyle('display', 'none');
            });
            return this;
        },

        addEvent: function(type, fn){
            var add = function(el){
                if(window.addEventListener){
                    el.addEventListener(type, fn, false);
                }else if(window.attachEvent){
                    el.attachEvent('on' + type, fn);
                }
            };
            this.each(function(el){
                add(el);
            });
        }
    };

    window.$ = function(){
        return new _$(arguments);
    }
})();

 

 看看该类每个方法的最后一行,你会发现他们都是以"return this;"结束,这样将用以调用方法的对象传给调用链上的下一个方法。





本文转自Barret Lee博客园博客,原文链接:http://www.cnblogs.com/hustskyking/archive/2012/09/18/3049802.html,如需转载请自行联系原作者

目录
相关文章
|
JavaScript 前端开发
利用JavaScript实现二级联动
利用JavaScript实现二级联动 要实现JavaScript二级联动效果,首先要确定需要哪些技术: 二维数组 for in循环 new Option(text,value,true,true) add(option,null) onchange() 表单事件 HTML代码: &lt;!-- &lt;input type=&quot;text&quot; id=&quot;text&quot;&gt; --&gt; 请选择省份: &lt;select name=&quot;&quot; id=&quot;provinces&quot;&gt; &lt;!-- &lt;option value=&quot;江苏省&quot;&gt;江苏省&lt;/option&gt;
|
JavaScript Android开发 iOS开发
html通过js调用ios或android代码
html通过js调用ios或android代码
57 0
|
JavaScript 前端开发
JavaScript函数柯里化的实现原理,进来教你完成一个自己的自动实现柯里化方法
JavaScript函数柯里化的实现原理,进来教你完成一个自己的自动实现柯里化方法
167 0
|
移动开发 JavaScript weex
weex开发 - 方法的映射,在weex调用fetch方法,实际调用同名的原生方法,在回调中把数据传递回js
weex开发 - 方法的映射,在weex调用fetch方法,实际调用同名的原生方法,在回调中把数据传递回js
170 0
|
移动开发 JavaScript weex
weex-自定义module,实现weex在iOS的本地化,js之间互相跳转,交互,传值(iOS接入weex的最佳方式)
weex-自定义module,实现weex在iOS的本地化,js之间互相跳转,交互,传值(iOS接入weex的最佳方式)
219 0
|
JavaScript
JS中实现或退出全屏
JS中实现或退出全屏
153 0
|
前端开发 JavaScript
前端:JS实现双击table单元格变为可编辑状态
前端:JS实现双击table单元格变为可编辑状态
365 0
|
JavaScript 算法 前端开发
【前端算法】JS实现数字千分位格式化
JS实现数字千分位格式化的几种思路,以及它们之间的性能比较
271 1
|
算法 前端开发 JavaScript
【前端算法】用JS实现快速排序
理解数组方法里面运用到的算法,splice 和 slice的区别
113 0