-2

I have this code example:

function s () {
    this.func = [];
    this.func.addF = function (str) {
        this.func.push(str);
    }
}

When I create an Instance of that object:

var a = new s ();
a.func.addF ("hello");

I get an error saying: Uncaught TypeError: Cannot read property 'push' of undefined.

I can understand that this.func is undefined at that point, but what should I do to make this work. Pls help.

Oriol
  • 274,082
  • 63
  • 437
  • 513
  • 1
    You're defining `this.func` as an array, but create an object property on top of it. – roberrrt-s Dec 23 '16 at 16:42
  • Your code is invalid brah. Should be this.addF not this.func.addF – Mike Doe Dec 23 '16 at 16:42
  • I know it's invalid. Could you guys pls show me what I should fix. –  Dec 23 '16 at 16:43
  • Just use `this.push` - within that function, the `this` object is (probably*) going to be the array object itself, not the outer object which contains the array. (* Depending on how addF is called) – PMV Dec 23 '16 at 16:43
  • Please state clearly what exactly you are trying to accomplish. – PM 77-1 Dec 23 '16 at 16:43
  • Anyway dont define methods inside your function. Use the prototype instead – Mike Doe Dec 23 '16 at 16:44
  • @mike Can you pls show me how to do that? –  Dec 23 '16 at 16:46
  • 1
    Related: http://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback – Felix Kling Dec 23 '16 at 17:02
  • Do not mutate your questions to something completely different. You can ask a new question. – Oriol Dec 23 '16 at 18:32
  • @Oriol Oh, I did that, and then people just started marking it as a duplicate for some reason –  Dec 23 '16 at 18:34
  • I have closed this to the canonical duplicate about `this`, and reopened your other question which is not related to `this`. – Oriol Dec 23 '16 at 18:38

2 Answers2

4

There is a problem with this. In javascript, this point to the binding context or what was used to invoke the function call. The value of this is determined by how a function is called.

function s () {
    var self = this;
     self.func = [];
    self.func.addF = function (str) {
        self.func.push(str);
    }
}

var a = new s ();
a.func.addF("hello"); // Display 'hello'
Abhinav Galodha
  • 9,293
  • 2
  • 31
  • 41
  • this was helpful. Thanx a lot –  Dec 23 '16 at 16:54
  • This will absolutely work, however do note it creates a closure that, in this instance, is unnecessary. This mechanism is needed if addF requires access to any other properties of the containing object, so it's a very useful pattern to know, but in this case there's an alternative that doesn't require creating a closure. – PMV Dec 23 '16 at 16:57
  • Actually, when thinking more about it, either method creates a closure, but the use of the `self` free variable guarantees that the outer scope must be captured and cannot be optimized away. – PMV Dec 23 '16 at 17:14
  • Hi, I edited my question. Could you pls have a look and help me with this similar bug? I just don't get it –  Dec 23 '16 at 17:58
4

Are you trying to add the method to the inner object (the array) or the outer object (the one constructed by s)?

If the function is intended to be added to the outer object

function s () {
    this.func = [];
    this.addF = function (str) {
        this.func.push(str);
    }
}

If the function is intended to be added to the inner (array) object

function s () {
    this.func = [];
    this.func.addF = function (str) {
        this.push(str);
    }
}

The reason has to do with how this is defined. When you call the method like this:

a.func.addF ("hello");

the variable this does not refer to a, it refers to a.func. a.func does not have a property func, but it does have the method push, so if you really intended to add the function to the array object itself, then just use this.push.

PMV
  • 2,058
  • 1
  • 10
  • 15
  • I meant the second one. Thanx a lot –  Dec 23 '16 at 16:49
  • Hi, I edited my question. Could you pls have a look and help me with this similar bug? I would really appreciate that –  Dec 23 '16 at 17:58