【Effective JavaScript】第44条: 使用 null 原型以防止原型污染

第44条: 使用 null 原型以防止原型污染

防止原型污染的最简单的方式之一就是一开始就不使用原型。但在ES5未发布之前,并没有标准的方式创建一个空原型的新对象。你可能会尝试设置一个构造函数的原型属性为 null或者undefined。

function C() { }
C.prototype = null

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

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

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

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

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

一些不支持Object.create函数的旧的JavaScript环境可能支持另一种值得一提的方式。 在许多环境中,特殊的属性一proto一(参阅第31条和第32条)提供了对对象内部原型链的读写访问。对象字面量语法也支持初始化一个原型链为null的新对象。

var x = { __proto__: null };
x instanceof Object               // false (non-standard)

这样的语法同样方便,但有了Object.create函数后,Object.create函数是更值得信赖的方式。__proto__属性是非标准的并且并不是所有使用都是可移植的。JavaScript的实现不能保证在未来任然支持它,所以应当尽可能地坚持使用标准的Object.create函数。

不幸的是,虽然非标准的__proto__可以解决一些问题,但也带来了自身额外的问题,即阻止自由原型(prototype-free)对象作为真正健壮的字典实现。第45条描述了在某些JavaScript环境中,属性关键字"__proto__"自身是如何污染对象的,甚至可以污染没有原型的对象。如果不确定字典中从未将字符串"__proto__"作为key使用,那么你就应当考虑使用第45条中描述的更健壮的Dict类。

提示

  • 在ES5环境中,使用Object.crate(null)创建的自由原型的空对象是不太容易被污染的。
  • 在一些较老的环境中,考虑使用{__proto__: null}
  • 但要注意__proto__既不标准,也不是完全可移植的,并且可能会在未来的JavaScript环境中去除。
  • 绝对不要使用"__proto__"名作为字典中的key,因为一些环境将其作为特殊的属性对待。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值