The dangers of rewriting object and JavaScript functions

The nature of JavaScript allows you to completely rewrite its own objects. I want to know if there is any real danger at the same time!

Here are some examples of inline JavaScript objects

Object Function Number String Boolean Math RegExp Array 

Suppose I want to model them so that they follow a similar pattern that you could find in Java (and some other OOP languages), so that Object defines a set of basic functions, and every other object inherits it (this would have been explicitly defined by the user , unlike Java, where everything naturally comes from the object)

Example:

 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); 

In this case, Object and Boolean now have new implementations. In this regard, what can happen? Can I break things further down the line?

Edit:

I read somewhere that frameworks like MooTools and Prototype have a similar approach to this, is this true?

+6
source share
4 answers

Monkey patching built-in classes, as this is a controversial topic. I personally do not like to do this in 2 sessions:

  • Built-in classes are global. This means that if two different modules try to add methods of the same name to the global classes, they will conflict, resulting in subtle errors. Even more subtly, if a future version of browsers decides to implement a method with the same name, you also have problems.

  • Adding things to prototypes of common classes can break code that uses in-in loops without checking hasOwnProperty (people new to JS often do this with objects and arrays because the appearance looks like a foreach loop). If you are not 100% sure that the code you use safely uses for-in loops, then monkeypatching Object.prototype can lead to problems.

However, there is one situation where I am compatible with monkeypatching built-in, and this is adding functions from new browsers to older browsers (for example, the forEach method for arrays). In this case, you avoid conflicts with future versions of the browser and are unlikely to catch anyone by surprise. But even then, I would recommend using a gasket from a third party instead of encoding it yourself, since there are often many complex angular cases that are difficult to obtain.

+4
source

There is some level of preference, but my personal approach is that this kind of potential has a huge gigantic mess.

For example, you start with two projects: A and B, each of which decides to implement all sorts of amazing useful current methods into String.

Project A decided that String needed the isEmpty function, which returns true if the string has zero length or only a space.

Project B decided that String needed the isEmpty function, which returns true if the string is of zero length, and the isEmptyOrWhitespace function, which returns true if the string is of zero length or only spaces.

Now you have a project that wants to use some code from Project A and some code from Project B. Both of them make extensive use of their custom functions isEmpty . Do you have a chance to join them successfully? Probably no. You are in a cluster arrangement, so to speak.

Please note that this is all very different from extension methods in C #, where you need to at least import the namespace of a static class to get the extension method, there is no conflict at run time and can reasonably consume from A and B in the same project if You did not import the extension namespace (hoping that they provided that for this reason their extension classes were in a separate namespace).

+1
source

The worst case in JS that I know from these lines is undefined . You can define it.

You are allowed to do things like undefined = 'blah'; .... at this point you can no longer rely on if(x === undefined) . Which can easily break something elsewhere in your code (or, of course, in a third-party library that you can use).

It completely wanders, but definitely shows a certain danger of arbitrary rewriting of embedded objects.

See also: http://wtfjs.com/2010/02/15/undefined-is-mutable

For a slightly more reasonable example, take the Sahi browser test tool . This tool allows you to write automatic browser scripts to check your site. (similar to selenium). One of the problems is that if your site uses alert() or confirm() , the script will stop working while it is waiting for user input. Sahi circumvented this by overwriting these functions with his own stub functions.

0
source

I avoid overriding the default behavior of inherent objects. It bit me a bit while the others were fine. An example is the Sugar.js library. This is a great library that some people love, but I generally avoid it simply because it extends the behavior of existing JavScript objects, such as what you are doing.

I think, however, that you will find that this is purely opinion and style.

0
source

All Articles