JavaScript链式调用

方法的链式调用

1. 调用链的结构

链式调用的核心就是在调用方法中返回调用该方法的对象的引用,即 return this;

下面我们模范 JQuery 来实现一个简单的链式调用接口,通过 $() 方法获取元素对象,并提供三个链式调用方法 each(callback)setStyleaddEvent

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

    _$.prototype = {
        each: function(fn) {
            for( var i=0, len=this.elements.length; i<len; i++) {
                fn.call(this, this.elements[i])
            }
            return this             // 返回调用函数的对象的引用
        },
        setStyle: function(prop, val) {
            this.each(function(el) {
                el.style[prop] = val;
            })
            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)
            })
            return this;
        }
    }

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

2. 获取链式调用方法的数据

如果需要通过某个方法获取对象的数据,我们一般的方法是通过 return 将数据返回,但是在链式调用中 return 已经被用来返回调用方法的对象的引用,所以不能通过这个方法来获取数据。所以在链式调用方法中获取数据需要通过回调函数来实现。

window.API = window.API || function() {
    var name = 'Hello world';
    this.setName = function(newName) {
        name = newName;
        return this
    };
    this.getName = function() {
        return name
    }
    this.getNameByCallback = function(callback) {
        callback.call(this, name)
        return this
    }
}

// usage 
var api = new API()
// 中断了链式结构
api.setName('cczs').getName()

// 没有中断链式,但是不能通过 return 返回,使得取值器也支持链式调用
api.setName('cczs').getNameByCallback(function(name){
    console.log(name)
})

posted @ 2018-03-02 01:02  另一个小菜头  阅读(578)  评论(0编辑  收藏  举报