为什么我们要删除全局对象的某些内置属性?


12

我最近正在阅读es5,发现在全局对象的某些内置属性中的[[configurable]]属性设置为true,这意味着我们可以删除这些属性。

例如:

Array.prototype对象的join方法具有属性

{[[Writable]]:true, [[Enumerable]]: false, [[Configurable]]: true}

因此,我们可以轻松删除Array的join方法,例如:

delete Array.prototype.join;
alert([1,2,3].join);

警报将显示 undefined在我的铬17,Firefox 9(即10,甚至ie6)中;

在Chrome 15和safari 5.1.1中,[[configurable]]属性设置为true,删除结果也为true,但最终结果仍为 function(){[native code]}。似乎这是一个错误,而铬修复了它。

我以前没注意到。我认为删除用户代码中的内置函数很危险,并且在与其他人一起工作时会带来很多错误。那么为什么ECMAScript会做出这个决定?


多个答案赞扬了通过删除属性来定制内置功能的能力,但是这种方法仅是必需的,因为该功能是硬连接在全局变量中的,而不是使用DI。似乎通过删除属性进行自定义是对根本上不良设计的攻击。例如,如果您需要能够更改JSON解析器,则可以编写将JSON解析器作为输入的代码。
恢复莫妮卡

Answers:


2

我倾向于同意您的观点,但另一方面,我发现delete JSON.stringify由于Firefox 3.5中的错误,在某些情况下我需要这样做。我当然很高兴能够在那里修补内置的猴子。


您为什么不覆盖它?
demix

2
因为接下来发生的事情是加载JSON2.js,它会检测JSON2.js的存在JSON.stringify并在必要时进行注入。抱歉,我没有在回答中解释这一点。
N3dst4

所以,你可以修改JSON2.js的源代码也一样,洛尔
demix

修改第三方库不是一个好主意,因为那样一来,您就无法在不复制所有更改的情况下升级它们。
N3dst4

1

可配置与删除无关。

它与替换只读值的能力有关。

这是一个非常强大的工具,如果无法删除它们,则不可配置的值会令人沮丧。

在很多情况下,我需要修复一个不起眼的错误或注入稍有不同的功能(拦截,日志记录)。这样做需要替换值。

例:

Object.defineProperty(Object.prototype, "foo", {
  value: 42,
  configurable: true
});

var o = {};
o.foo = 50; // fails. foo is not writable
delete Object.prototype.foo;
o.foo = 50; // succeeds
/* optionally put Object.prototype.foo back */

整个想法是,如果您可以删除属性,那么您将拥有更多的元编程控件。如果您无法删除它们,那么您只会对语言感到恼火。

没有充分的理由使物业无法删除,否则会惹恼人们。


1
[[writable]]属性控制更改值的能力。在ES5中:[[Writable]]布尔值如果为false,则ECMAScript代码尝试使用[[Put]]更改属性的[[Value]]属性不会成功。 .[[Configurable]]布尔值如果为false,则尝试删除该属性,将该属性更改为访问器属性或更改其属性([[Value]除外))将失败。
demix

@demix是的,这是正确的……
Raynos

0

..删除用户代码中的内置函数很危险

恰恰相反。允许自定义是好的因为它允许网站作者具有更大的灵活性。

如果网站作者需要在同一JS VM中加载第三方代码,希望使用内置的JS解析器来执行此操作,则他总是可以在加载第三方代码之前通过将属性设置为不可配置来保护属性。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.