一般大家推荐的都是使用Object.prototype.toString.call()进行数据判断,但是Object.prototype上的toString不是也可以被重写吗?为什么还会认为该方法是标准方法,因为其是最优解吗
一般大家推荐的都是使用Object.prototype.toString.call()进行数据判断,但是Object.prototype上的toString不是也可以被重写吗?为什么还会认为该方法是标准方法,因为其是最优解吗
27 回答13k 阅读
8 回答3.5k 阅读✓ 已解决
6 回答1.3k 阅读✓ 已解决
5 回答5.3k 阅读✓ 已解决
4 回答1.6k 阅读✓ 已解决
3 回答1.7k 阅读
4 回答2.3k 阅读✓ 已解决
没错,用这个方法是因为能准确判断出数据类型,你会发现很多第三方库的源码中都是用这个方式判断的数据类型。从实用性上来说,可以说是最优解了,一句代码就能达到目的。当然简单的类型直接用
typeof
或者其他内置的判断方法即可。使用
Object.prototype.toString.call
本身是为了防止你要判断的那个对象的toString
被重写,比如上面是为了防止对象
a
的toString
方法被重写,采取最终调用Object
原型上的方法来解决。但是你直接把
Object
原型上的toString
也重写就没辙了。都知道JS是基于原型的语言,你把原型上的方法都重写了不就肯定完蛋了么。angular曾经就有一个bug导致判断类型错误,原因就是
Object.prototype.toString
被重写了。如果你使用的这个版本之前的angular就完蛋了。https://github.com/angular/an...
再扩展一下,我还有更恐怖的做法,直接将
window.Object
、window.Array
重写,后续使用Object
和Array
的地方直接完蛋。那是不是Object.keys
或者Array.isArray
也不能用了?难道意味着这两个方法能被重写我们就不该使用它吗?这本身就是JS赋予的能力,JS中能被修改的对象就不存在绝对的安全性,但也正是这种特性,赋予了我们扩展JS自带对象的能力。不过话又说回来,由于Web端是以浏览器为宿主,并且是即时运行的。如果在你的源码干净(指没有用故意破坏原型方法的库) 的情况下,什么情况才会被别人篡改方法呢?
所以总结一下,你的问题不在JS方法的安全性上,而是如何防止代码注入的问题。