JS-coder
JS-coder

Reputation: 3271

Is it possible to overwrite javaScript primitive data type?

Question is self explanatory. I know it is possible to extend primitive data types such as string but is it possible to overwrite it?

This is a question that has been asked in an interview.

Upvotes: 4

Views: 2902

Answers (4)

oleq
oleq

Reputation: 15895

  1. You can extend prototypes of native types.

    String.prototype.moo = function() { 
       console.log( 'Moo!' ) 
    };
    'Cow says'.moo();
    >> "Moo!"
    
  2. However you cannot directly overwrite constructors of built-in types unless you overwrite the reference to the entire object:

    String = function() { 
       console.log( 'Custom function.' ) 
    };
    
    new String( 'Hello!' );
    >> "Custom function."
    >> String {} // now you've broken your website ;)
    
  3. ...but still:

    'Wat?!'
    >> "Wat?!" // you can still create strings by typing letters in quotes
    

So... the answer is "yes but no". You can mess with native types (Number, Date, String...) but you cannot re-define them entirely from scratch. They're a part of JS engine that you're using (most likely native C++ code) and this brings some limitations.

Upvotes: 1

Bergi
Bergi

Reputation: 664620

No, you cannot overwrite anything. EcmaScript defines the primitive types Undefined, Null, Boolean, Number, and String; these are internal and will be used regardless of what you are doing (for example overwriting the global String constructor). Type conversion and evaluation of literals does not rely on any public functions but uses only these internal types and the algorithms specified for them.

Of course, if someone does string coercion with String(myval) instead of ""+myval assigning to the global String variable will have an effect on that code. Any internal use would still point to the "old" function.


If you were talking about prototype objects for the primitive types (when used as objects), those are not overwritable as well. You may extend those objects, but as soon as you assign to e.g. Number.prototype you just have lost a reference to the actual, original number protype object. Example spec for The Number constructor:

The [prototype] of the newly constructed object is set to the original Number prototype object, the one that is the initial value of Number.prototype (15.7.3.1)

Upvotes: 2

Amrendra
Amrendra

Reputation: 2077

Possible like this but you must always succeed without side effects.Not good practice.

function Array() {
  var obj = this;
  var ind = 0;
  var getNext = function(x) {
    obj[ind++] setter = getNext;
    if (x) alert("Data stolen from array: " + x.toString());
  };
  this[ind++] setter = getNext;
}
var a = ["private stuff"];
// alert("Data stolen from array: private stuff");

Upvotes: 0

Barney
Barney

Reputation: 16456

Yes (edit: almost). Open up a Javascript console (F12 if you're using Chrome) and type

String = function(){alert('bang!')};

You can overwrite (edit: almost) everything in Javascript — even the window global context! evil.js is a library that uses this trick to rewrite many native objects as possible.

Needless to say, this is extremely dangerous. I performed the String remapping code above, and since writing it down I've caused over 520 Javascript errors (and I've seen 'bang' alerted quite a few times). Native objects are used everywhere, and you shouldn't modify these in case 3rd party code relies on them in ways you don't know about. This is one of the reasons Prototype.js lost popularity — because its extension of native objects would often work against the expectations of other code.

Edit: Factually incorrect assertion that absolutely everything could be overwritten, as pointed out in Bergi's answer. Edits made inline.

Upvotes: 1

Related Questions