Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
覆盖JavaScript对象和函数的危险_Javascript_Typescript_Ecmascript 5 - Fatal编程技术网

覆盖JavaScript对象和函数的危险

覆盖JavaScript对象和函数的危险,javascript,typescript,ecmascript-5,Javascript,Typescript,Ecmascript 5,JavaScript的本质允许完全重写其本机对象。我想知道这样做是否有真正的危险 下面是一些本机JavaScript对象的示例 Object Function Number String Boolean Math RegExp Array 让我们假设我想按照Java(和其他一些OOP语言)中的类似模式对它们进行建模,以便对象定义一组基本函数,并且每个其他对象都继承它(这必须由用户显式定义,不像Java,Java中的一切都是从对象自然派生的) 示例: Object = null; functio

JavaScript的本质允许完全重写其本机对象。我想知道这样做是否有真正的危险

下面是一些本机JavaScript对象的示例

Object
Function
Number
String
Boolean
Math
RegExp
Array
让我们假设我想按照Java(和其他一些OOP语言)中的类似模式对它们进行建模,以便对象定义一组基本函数,并且每个其他对象都继承它(这必须由用户显式定义,不像Java,Java中的一切都是从对象自然派生的)

示例:

Object = null;
function Object() {
   Object.prototype.equals = function(other) {
      return this === other;
   }

   Object.prototype.toString = function() {
      return "Object";
   }

   Object.equals = function(objA, objB) {
      return objA === objB;
   }
}

Boolean = null;
function Boolean() {
}
extend(Boolean, Object);  // Assume extend is an inheritance mechanism

Foo = null;
function Foo() {
   Foo.prototype.bar = function() {
      return "Foo.bar";
   }
}

extend(Foo, Object);
在这个场景中,Object和Boolean现在有了新的实现。在这方面,可能会发生什么?我有可能把事情进一步细分吗

编辑:

Object = null;
function Object() {
   Object.prototype.equals = function(other) {
      return this === other;
   }

   Object.prototype.toString = function() {
      return "Object";
   }

   Object.equals = function(objA, objB) {
      return objA === objB;
   }
}

Boolean = null;
function Boolean() {
}
extend(Boolean, Object);  // Assume extend is an inheritance mechanism

Foo = null;
function Foo() {
   Foo.prototype.bar = function() {
      return "Foo.bar";
   }
}

extend(Foo, Object);

我在某个地方读到,MooTools和Prototype等框架也有类似的方法,这是正确的吗?

据我所知,JS中最糟糕的情况是
未定义的
。你可以定义它

你可以做一些事情,比如
undefined='blah'。。。。此时,如果(x==未定义)
,您就不能再依赖
。这很容易破坏代码中的其他地方(当然,也可能是您正在使用的第三方库)

这完全是疯了,但绝对显示了任意覆盖内置对象的危险

另见:


举一个稍微理智一点的例子。此工具允许您为浏览器编写自动脚本以测试站点。(与硒类似)。这样做的一个问题是,如果您的站点使用
alert()
confirm()
,脚本将在等待用户输入时停止运行。Sahi通过使用自己的存根函数覆盖这些函数来解决这个问题。

我避免覆盖固有对象的默认行为。它咬了我几次,而其他人我还好。您可以查看的示例库是Sugar.js。这是一个很好的库,有些人喜欢,但我通常避免使用它,因为它扩展了现有JavScript对象的行为,比如您正在做的事情


不过,我想你会发现,这纯粹是观点和风格。

这里有一定程度的偏好,但我个人的看法是,这类事情有可能成为一个巨大的棘手的烂摊子

例如,您从两个项目(A和B)开始,每个项目都决定在String上实现各种非常有用的fluent方法

项目A决定
String
需要一个
isEmpty
函数,如果字符串长度为零或仅为空白,该函数将返回
true

项目B决定
String
需要一个
isEmpty
函数,如果字符串长度为零,则返回
true
;如果字符串长度为零或仅为空白,则需要一个
isEmptyOrWhitespace
函数返回
true

现在,您有一个项目希望使用项目a中的一些代码和项目B中的一些代码。这两个项目都广泛使用了它们的自定义
isEmpty
函数。你有机会成功加入这两个组织吗?可能不会。可以说,你处于集群安排中


请注意,这与C#中的扩展方法完全不同,在C#中,您至少必须导入包含静态类的名称空间才能获得扩展方法,没有运行时冲突,并且只要不导入它们的名称空间扩展,就可以合理地从同一项目中的A和B使用它们(正因为这个原因,希望他们有远见将扩展类放在一个单独的名称空间中)。

像这样修补内置类是一个有争议的话题。我个人不喜欢这样做有两个原因:

  • 内置类是一个全局作用域。这意味着,如果两个不同的模块试图向全局类中添加同名的方法,那么它们将发生冲突,从而导致微妙的错误。更微妙的是,如果浏览器的未来版本决定实现同名的方法,您也会遇到麻烦

  • 向公共类的原型中添加东西可能会破坏用于in循环的代码,而无需进行hasOwnProperty检查(JS新手通常会对对象和数组执行此操作,因为for in类似于foreach循环)。如果您不能100%确定所使用的代码是否用于安全的in循环,则monkeypatching Object.prototype可能会导致问题


  • 也就是说,有一种情况我认为monkeypatching内置是可以接受的,那就是在旧浏览器上添加新浏览器的功能(例如,数组的forEach方法)。在这种情况下,您可以避免与未来的浏览器版本发生冲突,也不可能让任何人感到意外。但即使如此,我仍然建议使用第三方的垫片,而不是自己编写,因为通常有许多棘手的情况很难纠正。

    来自
    对象的自动继承类也存在于javascript中!@MatteoTassinari,假设我这样做:var Foo=(function(){return Foo;});在本例中,Foo是一个函数()…那么Foo是如何自动继承对象的呢?@series0ne javascript中的所有内容都继承自
    对象
    。您可以执行
    。\uuuuuu proto\uuuuuu
    来查看它的来源。打开控制台并执行
    函数f(){}
    ,然后是
    f.\uuuu proto\uuuuu
    。你可以一直跟踪到object。js中的任何东西都可以这样说-字符串、数组,无论什么。(不包括
    null
    undefined
    ,但我希望这是给定的)@Snuffleupagus,谢谢!我会看一看的!@Snuffleupagus,我试过了:f.\uu proto\uu返回“function()”,但是f.uuu proto_uuu.uuuu proto_uuu返回“Object{}”…所以我猜甚至function()也是一个对象?请记录