0

Why is a custom method on an array not working here:

function runTestMethod() {
    alert("method running");
}

String.prototype.testMethod = runTestMethod;


var A = "A";
A = A.testMethod();         // WORKS


var B = new Array();
B[0] = "food";
B[1] = "bar";

B = B.testMethod();         // ERROR 'undefined' IS NOT A FUNCTION

B[0] = B[0].testMethod();       // ERROR 'undefined' IS NOT A FUNCTION

B[0] = B[0].slice(0,-1);        // WORKS

UPDATE: the answer is that I'm trying to use a String.prototype on an array. My method needs to be Array.prototype instead. Despite array "B" containing string members, these are still being treated as array-object-properties not actual strings. The factory method of slice() is confusingly designed to work on both strings and arrays. Thanks to T.J. Crowder for the explanation.

3
  • 2
    You attached it to string prototype, why would it be at array? Commented Feb 2, 2014 at 12:52
  • This concept may be beyond my limited knowledge of JS. Have I not created an "array" not "string prototype" with 'new Array()' ?? Commented Feb 2, 2014 at 12:54
  • "Despite array "B" containing string members, these are still being treated as array-object-properties not actual strings." B is an array containing entries. The entries in the array (in this case) are strings. slice isn't "designed to work on both strings and arrays," they just each have a function by that name (different functions that do similar, but different, things). Commented Feb 2, 2014 at 13:28

1 Answer 1

2

Because you've put it on String.prototype, rather than Array.prototype.

This line:

String.prototype.testMethod = runTestMethod;

adds to String.prototype, and so that property (and the function it refers to) is available on strings. You wanted to add to Array.prototype instead, so that the property (and the function it refers to) are available on arrays.

Complete example:

// v--- Notice this is `Array.prototype`!
Array.prototype.oddsOnly = function() {
    var rv = [], index;
    for (index = 1; index < this.length; index += 2) {
        rv.push(this[index]);
    }
    return rv;
};

// These are arrays      
var a = ["zero", "one", "two", "three", "four", "five", "six"];
var b = a.oddsOnly();
//        ^------------- function is available on arrays
console.log("a: " + a.join(", "));
console.log("b: " + b.join(", "));

Live Copy | Live Source

Output:

a: zero, one, two, three, four, five, six
b: one, three, five
Sign up to request clarification or add additional context in comments.

6 Comments

Hmm this is a bit over my head. I get the same problem if I create array members B[0] = 0; B[1] = 1; -- no strings involved?
@user3201867: Again: You're adding your function to strings, not to arrays. So you have the function available on strings, and you don't have it available on arrays. So when you create an array, it's no surprise the function isn't there.
Yes I think I see now -- if I just change String.prototype.testMethod to Array.prototype.testMethod that is the solution?
Though now I'm curious why a string prototype wouldn't actually work on "B[0] = B[0].testMethod()" -- referring to strings "food", "bar" -- but the string method of slice() does work on that...
@user3201867: slice happens to be a method both on strings and on arrays.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.