The question I have deals with an application of adding a new method to the existing String constructor. In Object Oriented Program for Javascript by Stoyan
Array.reverse
is undefined (at least in Chrome 29) - Array.prototype.reverse
is a function that will reverse the order of the "iterable" it is called on.
The key thing to note here is that Array
is not a class like you would have in Java - rather it is a constructor:
[].constructor === Array;
// true
The prototype
property of Array
is actually what is providing the behavior to any particular instance of Array
:
Object.getPrototypeOf([]) === Array.prototype;
// true
// Bad idea, just for an example
var guys = ['Tom', 'Harry', 'Richard'];
Array.prototype.exclaim = function() {
return this.join(", ") + "?!?!?!";
};
guys.exclaim();
// Tom, Harry, Richard?!?!?!
The key here is that JavaScript uses a prototype-based object-oriented pattern, rather than the classical pattern you are more likely familiar with. Instead of having "classes" which contain all the behaviors, but which are distinct from instances, JavaScript has objects, which can be the "prototypes" of other objects, providing data and behavior to the child objects.
// Totally licit OO pattern in JavaScript
var prototypeClass = {
method1: function() { console.log("Hello from method 1!"); },
method2: function() { console.log("Hello from method 2!"); },
classData: 42
};
var prototypeInstance = Object.create(prototypeClass);
prototypeInstance.method1() // Hello from method 1!
prototypeInstance.classData // 42
// And you can modify the class after
// instantiating instances and the changes
// will be picked up by the instances
prototypeClass.happyPrimes = "Don't they teach recreational mathematics anymore?";
prototypeInstance.happyPrimes // The quote from 42
Is it the case that I have to call upon prototype to access the .reverse() method from the Array object
No. To access a method on an object, just access it with dot notation. What you want to do is simply
return this.split('').reverse().join('');
That is just what apply (or call
) does:
var arr = this.split('');
return arr.reverse.apply(arr).join('');
and finally arr.reverse === Array.prototype.reverse
since that's where Array
objects do inherit from. You are not accessing the reverse
method on the Array
constructor function object itself, you are to access the property that all Array
instances share - via their prototype. Yet you hardly will ever need to use the prototype object explicitly, that's only when you're dealing with objects that are not Array
instances (do not share the prototype) like arguments
objects or NodeList
s.
TypeError: missing argument 0 when calling function Array.reverse
. That does not make any sense to me.
Array.reverse
is a non-standard Array generic method which is only available in Firefox. It's purpose is to simplify the construct of applying Array prototype methods on other objects, and it does take the array-like object as it's first parameter. An example:
Array.reverse([0, 1]) // [1, 0]
which is equivalent to
Array.prototype.reverse.apply([0, 1]);
However, you were doing
Array.reverse.apply([…]/*, undefined*/)
which is calling the Array.reverse
function with the array for the (irrelevant) this value and no actual argument, equivalent to
Array.prototype.reverse.apply(undefined)
and that throws the rightful exception.