-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
underscore源码剖析之基础方法 #3
Comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
underscore源码分析之基础方法
本文是underscore源码剖析系列的第二篇,主要介绍underscore中一些基础方法的实现。
mixin
在上篇文章underscore整体架构分析中,我们讲过**_上面的方法有两种挂载方式,一个是挂载到_构造函数上以_.map(arr)的形式直接调用(在后文上统称构造函数调用),另一种则是挂到_.prototype上以_(arr).map()的形式被实例调用(在后文上统称原型调用)**。
翻一遍underscore源码你会发现underscore中的方法都是直接挂到_构造函数上实现的,但是会通过mixin方法来将_上面的方法扩展到_.prototype上面,这样这些方法既可以直接调用,又可以通过实例来调用。
从这段代码中我们可以看出,mixin方法将_上的所有方法通过遍历的形式挂载到了_.prototype上面。
细心观察一下,构造函数调用和原型调用的区别在哪里?
没错,区别就在于调用方式和传参,构造函数调用时一般会把要处理的值当做第一个参数传入,而原型调用的时候会把要处理的值传入_构造函数来创建一个实例。
从上一节中我们知道,在创建一个_的实例时,会用this._wrapped将传入的值保存起来,所以在mixin里面这一句:var args = [this._wrapped];是将我们传给_的值放到args数组第一项中,之后再将arguments也放入args数组中,借助apply方法执行当前遍历的方法(在这个例子中是each),这个时候传给each方法的是arr和func,正好和原来直接_.each调用each传入参数的顺序是一样的(underscore中的方法第一项基本上都是要处理的数据)。
链式调用
那么上面最后return result(this, func.apply(_, args)),result又是做什么的呢?
首先来看result源码:
我们知道underscore中也是有和jQuery类似的链式调用,来看一下链式调用的例子:
链式调用的关键在于每次执行方法后都需要返回一个实例,以确保能够继续调用其他方法。
chain方法会用传入的obj创建一个_的实例,这个实例可以调用原型上的方法。从上面mixin的实现来看,每次调用原型方法后会将执行后的结果传给result方法,在result内部会判断你是否使用了链式调用(chain),如果是链式的,那么就会将返回结果链式化(传入chain中创建新的实例)。
链式调用一定要在结尾执行value方法,不然最后返回的是一个对象(最后一次创建的_实例)
数组函数
underscore构造方法上面并没有直接对push、pop、shift等数组方法进行实现,但是链式调用的时候往往需要用到这些方法,所以在原型上对这些方法做了一些封装,实现方法和mixin类似,这里不再多做解释。
The text was updated successfully, but these errors were encountered: