第43条中讲到的就算是用了Object的直接实例,也无法完全避免,Object.prototype对象修改,造成的原型污染。防止原型污染最简单的方式之一就是不使用原型。在ES5之前,并没有标准的方式创建一个空原型的新对象。

尝试

设置构造函数的原型属性为null或undefined

function C(){}
C.prototype=null;

结果

实例化该构造函数仍然得到是Object的实例。

var c=new C();
Object.getPrototypeOf(c) === null;//false
Object.getPrototypeOf(c) === Object.prototype;//true

ES5标准方法

ES5提供了标准方法来创建一个没有原型的对象。Object.create函数能够使用一个用户指定的原型链和一个属性描述符动态地构造对象。属性描述符描述了新对象属性的值及特性。通过简单传递一个null原型参数和一个空的描述符,就可以建立一个真正的空对象。

var x=Object.create(null);
Object.getPrototypeOf(x)==null;//true

原型污染无法影响这样的对象。

兼容版本

一些不支持Object.create函数的旧的js环境可能支持__proto__属性,对象字面量也支持初始化一个原型链为null的新对象。

var x={__proto__:null};
x instanceof Object;//false

上面的方法也很有效,但在有标准方法后,标准方法是更好的选择。

注意

__proto__属性是非标准的并且并不是所有环境都可以移植的。js的实现者们并不能保证以后仍然支持它,所以有标准方法,尽量先考虑标准方法。
可以看出,虽然__proto__可以解决问题,但也引入它自身平台不兼容的问题,阻止自由原型对象作为真正健壮的字典实现。更健壮的方法,在下一条中会提到。

提示

  • 在ES5环境中,使用Object.create(null)创建的自由原型的空对象是不太容易被污染的

  • 在一些较老的环境中,考虑使用{__proto__:null}

  • 但要注意__proto__既不标准,也不是完全可移植的,并且可能会在未来的js环境中去除

  • 绝不要使用"__proto__"名作为字典的key,因为一些环境将其作为特殊的属性对待。

[Effective JavaScript 笔记]第44条:使用null原型以防止原型污染的更多相关文章

  1. [Effective JavaScript 笔记] 第4条:原始类型优于封闭对象

    js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...

  2. [Effective JavaScript 笔记] 第5条:避免对混合类型使用==运算符

    “1.0e0”=={valueOf:function(){return true;}} 是值是多少? 这两个完全不同的值使用==运算符是相等的.为什么呢?请看<[Effective JavaSc ...

  3. [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码

    函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式 ...

  4. [Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法

    js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...

  5. [Effective JavaScript 笔记]第45条:使用hasOwnProperty方法以避免原型污染

    之前的43条,44条讨论了属性的枚举,但都没有彻底地解决属性查找中原型污染的问题.看下面关于字典的一些操作 'zhangsan' in dict; dict.zhangsan; dict.zhangs ...

  6. [Effective JavaScript 笔记]第68条:使用promise模式清洁异步逻辑

    构建异步API的一种流行的替代方式是使用promise(有时也被称为deferred或future)模式.已经在本章讨论过的异步API使用回调函数作为参数. downloadAsync('file.t ...

  7. [Effective JavaScript 笔记]第67条:绝不要同步地调用异步的回调函数

    设想有downloadAsync函数的一种变种,它持有一个缓存(实现为一个Dict)来避免多次下载同一个文件.在文件已经被缓存的情况下,立即调用回调函数是最优选择. var cache=new Dic ...

  8. [Effective JavaScript 笔记]第66条:使用计数器来执行并行操作

    第63条建议使用工具函数downloadAllAsync接收一个URL数组并下载所有文件,结果返回一个存储了文件内容的数组,每个URL对应一个字符串.downloadAllAsync并不只有清理嵌套回 ...

  9. [Effective JavaScript 笔记]第65条:不要在计算时阻塞事件队列

    第61条解释了异步API怎样帮助我们防止一段程序阻塞应用程序的事件队列.使用下面代码,可以很容易使一个应用程序陷入泥潭. while(true){} 而且它并不需要一个无限循环来写一个缓慢的程序.代码 ...

随机推荐

  1. libtool: Version mismatch error 解决

    在编译一个软件的时候,在 ./configure 和 make  之后可能会出现如下错误: libtool: Version mismatch error.  This is libtool 2.4. ...

  2. sql server 2008 数据库的完整性约束

    一.数据库完整性概述   1.数据库的完整性:   ①数据库的完整性是指数据的正确性和相容性 ②数据库完整性是防止不合语义或不正确的数据进入数据库 ③完整性体现了是否真实地反映现实世界   例:  学 ...

  3. VS2010版快捷键

    VS2010版快捷键 Ctrl+E,D ----格式化全部代码 Ctrl+E,F ----格式化选中的代码 CTRL + SHIFT + B生成解决方案 CTRL + F7 生成编译 CTRL + O ...

  4. JAVA中的NIO(一)

    1.IO与NIO IO就是普通的IO,或者说原生的IO.特点:阻塞式.内部无缓冲,面向流. NIO就是NEW IO,比原生的IO要高效.特点:非阻塞.内部有缓存,面向缓冲. 要实现高效的IO操作,尤其 ...

  5. DOM(六)事件类型

    对于用户事件类型而言,最常用的是鼠标.键盘.浏览器. 1.鼠标事件: 鼠标的事件都频繁使用,下面例子就测试各种鼠标事件 <script language="javascript&quo ...

  6. jquery tree events didn't work

    You should put your js in $(document).ready() like following. Hope this will help you. $(document).r ...

  7. 图书封面制作-ps图片处理使用教程

    这是一个实用而有趣的教程,在这个PS教程中,我们来学习如何使用photoshop制作一个立体的软件产品盒子. 1.首先运行photoshop创建一个500*500像素的新文件,背景颜色为白色,如图所示 ...

  8. [转] 再探java基础——break和continue的用法

    原文地址:http://blog.csdn.net/luoweifu/article/details/10756017 break break可用于循环和switch...case...语句中. 用于 ...

  9. iOS8跳到系统设置页面

    iOS5.1+之后跳转setting页面的方式都失效了,不过在iOS8苹果有提供了一个键值允许app跳转到setting页面,具体代码如下: NSURL *url = [NSURL URLWithSt ...

  10. Java的多线程机制系列:(三)synchronized的同步原理

    synchronized关键字是JDK5之实现锁(包括互斥性和可见性)的唯一途径(volatile关键字能保证可见性,但不能保证互斥性,详细参见后文关于vloatile的详述章节),其在字节码上编译为 ...