javascript判断数据类型时,重写Object.prototype.toString?

一般大家推荐的都是使用Object.prototype.toString.call()进行数据判断,但是Object.prototype上的toString不是也可以被重写吗?为什么还会认为该方法是标准方法,因为其是最优解吗

阅读 1.6k
1 个回答

没错,用这个方法是因为能准确判断出数据类型,你会发现很多第三方库的源码中都是用这个方式判断的数据类型。从实用性上来说,可以说是最优解了,一句代码就能达到目的。当然简单的类型直接用typeof或者其他内置的判断方法即可。

使用Object.prototype.toString.call本身是为了防止你要判断的那个对象toString被重写,比如

var a = [];
Object.prototype.toString.call(a);

上面是为了防止对象atoString方法被重写,采取最终调用Object原型上的方法来解决。
但是你直接把Object原型上的toString也重写就没辙了。都知道JS是基于原型的语言,你把原型上的方法都重写了不就肯定完蛋了么。

angular曾经就有一个bug导致判断类型错误,原因就是Object.prototype.toString被重写了。如果你使用的这个版本之前的angular就完蛋了。
https://github.com/angular/an...

再扩展一下,我还有更恐怖的做法,直接将window.Objectwindow.Array重写,后续使用ObjectArray的地方直接完蛋。那是不是Object.keys或者Array.isArray也不能用了?难道意味着这两个方法能被重写我们就不该使用它吗?

这本身就是JS赋予的能力,JS中能被修改的对象就不存在绝对的安全性,但也正是这种特性,赋予了我们扩展JS自带对象的能力。不过话又说回来,由于Web端是以浏览器为宿主,并且是即时运行的。如果在你的源码干净(指没有用故意破坏原型方法的库) 的情况下,什么情况才会被别人篡改方法呢?

  1. 客户端注入脚本的方式,比如浏览器插件。但是这种方式只能影响单个浏览器,没有装这个插件的浏览器就不会有问题。
  2. 服务端在生成的HTML中注入了脚本,这种方式更危险,无论哪个用户访问你的网站,该脚本都会运行,达到破坏的目的。

所以总结一下,你的问题不在JS方法的安全性上,而是如何防止代码注入的问题

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏