3

I have to figure out, how to develop oop-javascript the right way. I read a lot about prototypes but the internet explained to me, I need it only, if I create an object a lot of times. But my SuperInterface exists only once. So I created it as an object:

var SuperInterface = {
    superaction: function () {
        alert(1);
    },
    actions: [{
        title: 'This is great',
        do_this: this.superaction
    }],
    init: function () {
        console.log(this.actions[0].title);
        this.actions[0].do_this();
    }
};
SuperInterface.init();

Running init() puts the title successfully to the console. But the alert is never called. I do not understand, why not? What should I change?

1

3 Answers 3

6

The value of this in the middle of that object initializer is not a reference to the object that is "under construction". There is no way to get such a reference during initialization since the object doesn't yet exist, and nor would you reference it with this. So you really can't initialize a property like that. You can however split it out into a separate statement:

var SuperInterface = {
    superaction: function () {
        alert(1);
    },
    actions: [{
        title: 'This is great',
        do_this: null;
    }],
    init: function () {
        console.log(this.actions[0].title);
        this.actions[0].do_this();
    }
};
SuperInterface.actions[0].do_this = SuperInterface.superaction;
Sign up to request clarification or add additional context in comments.

7 Comments

There is no way to get such a reference. See my answer.
@Vidul that does work in this case, but it's still true that there's no way to obtain a reference to an object in the middle of the object literal that describes it.
I don't see how your statement relates to a possible fix. I also don't see how your statement There is no way to get such a reference is not false.
@Vidul Can you show me an example of how it's possible to obtain a reference to an object that's "under construction"? Your solution is a good one, but (A) it does not involve getting a reference to the object while it is under construction, and (B) it will stop working if the variable "SuperInterface" takes on a new value. There simply is no way to do it in JavaScript; the language does not provide a mechanism for it (at least, not in ES5).
(B) it will stop working if the variable "SuperInterface" takes on a new value ?! Please elaborate.
|
2

If you debug this code, you will find SuperInterface.actions[0].do_this is undefined The reason is quite obvious. At the time of evaluation of code.

  actions: [{
        title: 'This is great',
        do_this: this.superaction
    }]

this.superaction, here this points to the window object.

and in this window object superaction does'nt exits..

To make this work eventually you need to

var SuperInterface = {
    superaction: function () {
        alert(1);
    },
    actions: [{
        title: 'This is great',
        do_this: null
    }],
    init: function () {
        console.log(this.actions[0].title);
        this.actions[0].do_this();
    }
};
SuperInterface.actions[0].do_this = SuperInterface.superaction;
SuperInterface.init();

I hope you got the answer. Thanks

1 Comment

this is never a reference to any part of any objects being initialized. It's whatever it is in the context of the outer var declaration. Object initializer expressions do not affect this, in other words.
0

var SuperInterface = {
    superaction: function () {
        alert(1);
    },
    actions: [{
        title: 'This is great',
        do_this: function() {
          return SuperInterface.superaction();
        }
    }],
    init: function () {
        console.log(this.actions[0].title);
        this.actions[0].do_this();
    }
};
SuperInterface.init();

this in your case refers to the literal object inside the array actions - it does not contain the method superaction.

12 Comments

I'm guessing the downvote is for your final remark. this refers to the global object.
In the original Q. it is the global object (assuming no other context).
The value of this is never affected by an object literal expression. The only thing that sets this is function invocation or entry into a "global" scope. An object literal does not change this.
In your JSFiddle, the function is called after the object has been constructed. The value of this is what it is because of that function call being made.
@Vidul it's a hard concept to communicate. Your anonymous function can get a reference, that is true - but it gets the reference after the object has been constructed. You obviously know JavaScript so that seems really obvious probably, but this question comes up a lot on StackOverflow. People expect this to refer to the object being built, which is not crazy or dumb but it's just not how JavaScript works.
|

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.