Friday, March 27, 2015

Extending Native Types in JS

Saw this as an interview question the other day, and thought it was pretty interesting.
The question, in its original form is:

Define a repeatify function on the String object. The function accepts an integer that specifies how many times the string has to be repeated. The function returns the number of times specified. For example:

console.log('hello'.repeatify(3)); 

prints hellohellohello


The first step in attacking this problem is to realize what it is asking us to do. We need to define a property on the String object that we can use on native string types like 'hello'. More to the point, we need to define this on the prototype object of String so that 'hello' can find it via [[prototype]] delegation. This, we want something like:

String.prototype.repeatify = function(n){
 var ret = '';
 for(var i = 0; i < n; i++){
  ret += this;
 }
 return ret;
}

console.log('hello'.repeatify(3)); //hellohellohello

This is great, and does what we want. But there is something missing here - can you spot it?

What if we are trying to polyfill this repeatify function, but it already exists (or may exist) on String? Our above code would simply overwrite the existing functionality, which is probably bad. Thus, we add an extra step:

String.prototype.repeatify = String.prototype.repeatify || function(n){
 var ret = '';
 for(var i = 0; i < n; i++){
  ret += this;
 }
 return ret;
}

console.log('hello'.repeatify(3)); //hellohellohello

And that's it!

No comments:

Post a Comment