我一直在使用JavaScript中的调用方法,我发现了一些有趣的东西:
我正在创建自定义地图功能,我做了类似的事情:
function map(collection, callback, context) {
if (!collection || !collection.hasOwnProperty('length') || typeof(callback) !== 'function') {
throw new TypeError();
}
var newArray = [];
var isFunction = typeof(callback.call) === 'function'; // this I added after to prove my point.
console.log('is callback.call a function? ' + (isFunction ? 'yes it is!' : 'no, it is not a function'));
for (var i = 0, len = collection.length; i < len; i++) {
newArray[i] = callback.call(context, collection[i], i, collection);
}
return newArray;
}
此时我使用以下参数执行了map
函数:
var arr = map(Array.apply(null, { length: 2 }), Number.call);
我跳过了上下文参数的值,因此它是undefined
。哪个应该很酷。另外有点奇怪的是callback
我最后通过call
方法:我在call
方法上调用call
方法(这也很酷)。
但由于未知原因,浏览器会给我这个错误:
is callback.call a function? yes it is!
Uncaught TypeError: callback.call is not a function
at map (eval at map (:10:9), <anonymous>:10:32)
at eval (eval at map (:10:9), <anonymous>:15:11)
at map (<anonymous>:10:9)
at <anonymous>:1:1
我想知道这背后的真正原因是什么。 callback.call
肯定是一个功能。 有没有办法处理这种情况?如何检查提供的参数是否会给我这样的错误?
当我提供背景时:
map(Array.apply(null, { length: 2 }), Number.call, Number)
// is callback.call a function? yes it is!
// [0, 1]
CodePen(在控制台中错过了一个错误,我建议使用浏览器重现)
编辑: 只是为了澄清上下文根本不需要:
map([1, 2], function(i) {
return i + 5;
});
// is callback.call a function? yes it is!
// [6, 7]
EDIT#2 我可以看到其他问题与我的关系如何。他们解释了这背后的原因,同样在Firefox上也有相当不错的错误信息:
TypeError: Function.prototype.call called on incompatible undefined
所以我的最后一个问题是:
有没有办法检测到这种&#34;不兼容&#34;?
答案 0 :(得分:1)
您正在将Number.call
函数作为参数传递。因此,在map
函数callback
变量中,现在已经是Number.call
函数了。那你就不应该再使用callback.call
了。只需使用callback
即可。
这只是我的2美分想法。希望它有所帮助!
编辑:因为call
是Function.prototype
的功能所以它会出现在每个函数实例中。它需要this
上下文才能成为一个函数。现在,您将Number.call
传递给新的map
,您已经丢失了上下文,因为在新的map
内,this
不再是一个功能。