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,如需转载请自行联系原作者

目录
相关文章
|
2月前
|
数据采集 JavaScript 前端开发
JavaScript中通过array.filter()实现数组的数据筛选、数据清洗和链式调用,JS中数组过滤器的使用详解(附实际应用代码)
JavaScript中通过array.filter()实现数组的数据筛选、数据清洗和链式调用,JS中数组过滤器的使用详解(附实际应用代码)
|
4月前
|
存储 JSON 前端开发
JavaScript异步编程3——Promise的链式使用
JavaScript异步编程3——Promise的链式使用
48 0
|
7月前
|
前端开发 JavaScript
JavaScript中链式调用大合集、应付面试够够的
JavaScript中链式调用大合集、应付面试够够的
|
JavaScript 算法 前端开发
【前端算法】JS实现数字千分位格式化
JS实现数字千分位格式化的几种思路,以及它们之间的性能比较
356 1
|
存储 前端开发 算法
一行代码解决LeetCode实现 strStr()使用JavaScript解题|前端学算法
一行代码解决LeetCode实现 strStr()使用JavaScript解题|前端学算法
170 0
一行代码解决LeetCode实现 strStr()使用JavaScript解题|前端学算法
|
存储 机器学习/深度学习 JavaScript
JS 你最少用几行代码实现深拷贝?
JS 你最少用几行代码实现深拷贝?
JS 你最少用几行代码实现深拷贝?
|
JavaScript 前端开发 算法
JavaScript实现一段时间之后关闭广告
简介:通过JavaScript实现在一段时间之后,广告消失。
138 0
JavaScript实现一段时间之后关闭广告
|
JavaScript 前端开发 算法
JS实现鼠标悬停变色
本文实现的是利用JS实现当鼠标悬停在表格上的时候,表格发生变色。 CSS渲染 JS逻辑 `
225 0
JS实现鼠标悬停变色
|
JavaScript 前端开发 数据安全/隐私保护
JS实现关闭图片窗口
通过事件的绑定来实现,关闭二维码的效果。
165 0
JS实现关闭图片窗口
|
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;