zepto.init中在判断函数这块有一个方法叫做isFunction()。字面上来看显而易见是判断是否为函数,深入底层来看一下它是如何来实现的
首先看一下它在init()函数中是如何被调用的:
else if (isFunction(selector)) return $(document).ready(selector)
然后看看zepto中isFunction()的位置:在全局中定义的方法。
function isFunction(value) { return type(value) == "function" }
显然,type(value)函数可以返回value的值。那我们再去看type函数:
//type用于返回对象类型,class2type[]中存在对应属性 function type(obj) { return obj == null ? String(obj) : class2type[toString.call(obj)] || "object" }
如果对象是null,则返回"null“,如果存在对象,则用toString.call(对象)调用,并且在class2type这个对象数组中找到对应的值,没有的话返回object
先将一下这个toString方法,可以返回对象的类型,例如下面的例子会依次返回[object Array];[object Number];[object Boolean];
document.write(toString.call([1,2])) document.write(toString.call(1)) document.write(toString.call(true))
了解了tostring之后,我们来看看class2type是个什么对象。首先它是被在zepto函数顶部声明了的,是一个对象
class2type = {},
按照之前的思路class2type应该是一个对象数组,看了下面这段代码你就明白了:
$.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { class2type[ "[object " + name + "]" ] = name.toLowerCase() })
用$.each()方法,将内置对象添加到class2type中,并给class2type定义了很多个属性,属性值就是对应的name小写名称,即name.toLowerCase()是一个js内置方法
很显然,到这里这个isFunction()方法就一目了然了。总结一下:
传入需要检测的参数---递传入type()函数判断---type函数利用了class2type的对象数组使其转换成对应的对象名称---返回。
讲到这里在顺便提一下,zepto还有一个方法叫$.isFunction()和$.type(),用于判断对象的类型,其实跟这里我们讲的isFunction()函数是一样的,只是zepto中加了一行:
$.type = type $.isFunction = isFunction $.isWindow = isWindow $.isArray = isArray $.isPlainObject = isPlainObject
明白了吧,将内部的函数方法通过 $.函数名=函数名 这种方法暴露出去,而$就是这个接口。