Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

不要随便拿对象字面量当 Map 用

  JavaScript 中的对象本身就是一个 hash 存储的 key-value 结构,于是经常被直接当 Map 来用。但是不要忘记了对象字面量本身是继承自 Object 的,也就是说这些对象可以访问到 Object 原型上的属性。那么如果 key 为一些本来就有的东西,判断就会遇到问题。
  下面是个时间复杂度 O(n) 的字符串数组去重的代码(ES5,这里不扯 ES6+) <script> var input = [ 'a', 'b', 'b', 'c' ]; var output = []; var map = {}; var str; for(var i = 0; i < input.length; i++) { str = input[i]; if(map[str]) continue; output.push(str); map[str] = true; } alert(output); </script>   乍看之下逻辑并没有什么问题,而且执行结果也是正确的。但是如果输入的数据中带有一些奇奇怪怪的东西呢?比如 <script> var input = [ 'a', 'toString', 'toString', 'valueOf', 'c' ]; var output = []; var map = {}; var str; for(var i = 0; i < input.length; i++) { str = input[i]; if(map[str]) continue; output.push(str); map[str] = true; } alert(output); </script>   由于 toString 和 valueOf 是继承自 Object 的两个方法,所以代码中 if 处就直接 continue,这个结果不会被放入 output 中,于是结果是错误的。所以直接拿对象字面量当 Map 用是有坑的。如果浏览器支持 Object.create 可以创建一个原型为 null 的对象。这样才能得到正确的结果 <script> var input = [ 'a', 'toString', 'toString', 'valueOf', 'c' ]; var output = []; var map = Object.create(null); var str; for(var i = 0; i < input.length; i++) { str = input[i]; if(map[str]) continue; output.push(str); map[str] = true; } alert(output); </script>
网名:
34.203.245.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^