我刚看到一个有代码的博客帖子
if(Object.prototype.toString.call(callback) !== '[object Function]'){
return new TypeError(callback + ' is not a function');
};在这种特殊情况下,由于我们可以使用typeof callback,所以它看起来有点过于工程化了。对于这段代码,我没有看到typeof callback没有给出正确答案的情况。更重要的是,原型可能会被覆盖,并开始给出错误的答案,而typeof却不能。
例如:
Object.prototype.toString = function(){return '[Object String]';};
Object.prototype.toString.call([])
// logs "[Object String]"问题:是否存在typeof会失败的情况(假定这一行的目的是检查变量是否是函数)?
我认为它更正确,语义,而不是过度工程使用:
if(typeof callback !== 'function'){
return new TypeError(callback + ' is not a function');
};发布于 2019-10-07 03:39:47
Object.prototype.toString检查来自ES5和早期,当时无法通过自定义Symbol.toStringTag实现伪造该方法的结果。然而,即使这样,如果希望对这些测试非常严格,通常在初始评估时就必须获取对toString函数的引用,因为Object.prototype.toString本身可以被覆盖--就像Function.prototype.call一样。
现在,以这种方式执行类型检查是没有意义的,而且即使在当时,它也是不必要的。然而,在过去,浏览器中有许多平台对象从the返回唯一的字符串,这很可能是以这种方式执行测试的动机之一。现在只剩下一种奇怪的情况:typeof document.all返回未定义的,但它实际上是一个函数。
不过,你喜欢类型的本能仍然是正确的。在几乎任何代码中,document.all的情况可能都不值得担心,即使是这样,toString检查也不可靠。真正可靠(偏执)检查的一个例子是:
var _Object = Object;
function isObject(value) {
return _Object(value) === value;
}
function isFunction(value) {
return typeof value === 'function' || (isObject(value) && typeof value === 'undefined');
}
console.log(isFunction(function() {})); // true
console.log(isFunction(document.all)); // true因此,您标记的“问题”部分的答案是“是的”,有一种情况是,n ===‘函数’类型返回一个误导性字符串,历史上还有其他情况。
更多的是关于“过度工程”的问题:也许作者在过去的一段时间里把它作为一种“最佳实践”学到了,并且已经有一段时间没有对它进行评论了,因为,嘿,这是他们熟悉的东西,起作用了,等等。虽然有更好的选择,但如果情况过度,我不会称之为尴尬。至少对我来说,过度工程指的是比这更高层次的东西--建筑选择,等等那些难以重构的东西。
就我个人而言,我建议,如果您编写的代码经常执行早期输入验证,那么避免直接使用typeof of仍然是个好主意。在JS中测试“type”通常不是那么简单,所以像上面示例中那样的isSomething函数集合可以帮助抽象出更古怪的实现细节,并带来一些一致性和可读性。作为函数,它们也更灵活(例如,arr.filter(isFunction))。有些流行的lib提供这样的实用程序,如果使用它们,通常不需要担心它是如何实现的。
https://stackoverflow.com/questions/58262940
复制相似问题