13

相信很多小伙伴在面试的过程中都被问过js链式调用的原理,甚至有些面试官还会让你用其实现例如加法操作,举例:

add(1)(2)(3)    //6

第一次看到这个题目时,或许你没有什么头绪,不要紧,让我们慢慢来;首先,大家还是否记得在使用jQuery时,我们会经常这样去操作一个jQuery节点

$("elem").show().css("color","red");

这是怎么做到的?原理很简单:就是jQuery节点在调用api后都会返回节点自身,类似于:

var Obj = {
    a: 1,
    func: function(){
        this.a += 1;
        return this
    }
}
Obj.func().func();
console.log(Obj.a);    //3

现在大致理解了链式调用的原理了吧!然后我们再来看如何实现文章开头的题目;首先我们来分析一下有哪几点是我们需要注意的:

  1. add函数在后续的链式调用时,应该记录之前的加和,如何实现?

  2. add函数在每次调用后既要保留自身的引用,又要返回操作结果,如何实现?

先上代码,然后我们逐一分析

function add (num) {
    var count = num;
    var _b = function(l){
        count += l;
        return _b
    }
    _b.valueOf = function(){
        return count
    }
    return _b
}
var c = add(1)(2)(3);
console.log(c)    //6

下面我们来详细分析一下代码:
1.首先,在add方法内部,我们是通过私有的_b方法实现的加法,而不是在add方法自身实现的,这里涉及到了函数式编程,这个概念我们就不在此做展开了,有兴趣的童鞋可以自己研究一下,可以说这是一种很不错的开发模式;add第一次执行后,返回了_b方法
2.在返回的_b方法中我们形成了对count的闭包,这样我们可以实现累计加和;还有一点需要注意,就是_b方法每次执行时都返回了它自身,这就实现了链式
3.最后,也是比较关键的,就是在输出add的结果,即add(1)(2)(3)的结果时,如何让它输出count,这里涉及了valueOf和toString方法的知识,还是那句话,感兴趣的童鞋可以自己研究一下;在这里最后能够正确输出6的原理是:_b是Function,是Object的一种特殊形式,当我们做类似打印console等操作时,会自动调用其valueOf方法(其实底层实现没有我说的这么简单,哈哈,但是大概是这么个意思),所以我们重写了valueOf方法来达到返回count的目的


结语
以上就是我对链式调用的一个粗略认识,有些概念可能表达的不是很清晰;其实楼主的目的就是想引导大家去研究一下链式调用所涉及到的一些js知识,不喜请轻喷O(∩_∩)O哈哈~


郭某某
223 声望6 粉丝

千里之行,始于足下