function isFunction(it) {
return ostring.call(it) === '[object Function]';
}
//ostring = Object.prototype.toString;
这是require.js中用于判断一个对象是否是方法的方法。。
这里就有一个疑问,为什么不直接 return it.toString() === '[object Function]'呢?
主要的原因在于,javascript的许多内置对象(准确的说是他们的显式原型prototype)都重写了Object.prototype的toString函数(尝试查看toString函数代码结果是function toString(){[native code]})
类型 | 行为描述 |
---|---|
Array | 将 Array 的每个元素转换为字符串,并将它们依次连接起来,两个元素之间用英文逗号作为分隔符进行拼接。 |
Boolean | 如果布尔值是true,则返回"true"。否则返回"false"。 |
Date | 返回日期的文本表示。 |
Error | 返回一个包含相关错误信息的字符串。 |
Function | 返回如下格式的字符串,其中 functionname 是一个函数的名称,此函数的 toString 方法被调用: "function functionname() { [native code] }" |
Number | 返回数值的字符串表示。还可返回以指定进制表示的字符串,请参考Number.toString()。 |
String | 返回 String 对象的值。 |
Object(默认) | 返回"[object ObjectName]",其中 ObjectName 是对象类型的名称。 |
而且很明显这些方法内部都是通过this获得方法的调用者并进行判断,最后得到结果,因此就很容易理解require.js为什么要这么写了,如果一个function对象直接调用it.toString得到的是方法描述,另外Object.prototoype的toString方法,适用于所有对象。
现在给出两个有意思的例子
var a = function(){};
var b = {a:1};
alert(Object.toString.call(a));//function(){}
alert(a.toString.call(b));//Uncaught TypeError:Function.prototype.toString is not generic at Object.toString(<anonymous>) at 代码位置
第一个得到function(){},而不是[object Function]的原因是Object是由Function生成的,所以它的原型链式Object--Function.prototype--Object.prototype--null(可以看继承一文),它的toString方法最先找到的是Function的
第二个报错的原因是Function的toString方法只能处理function对象,遇到其他对象直接抛出错误