0

I am trying to create a basic javascript framework that you can pass different things into, including functions for it to execute later. Right now, I'm in a more simple testing phase, but I can't quite get the function calling to work. A piece of my code is here:

[My JS Fiddle][1]http://jsfiddle.net/mp243wm6/

My code has an object that holds different data, and I want to call the method later, but with data that is available at the time of creation. Here is a code snippet of the function that uses the function that is passed to the object:

clickMe : function() {
        this.obj.click(function() {
            this.func();
        });
    }

Any suggestions or things I should read are welcome.

3
  • 1
    this is not what you think it is. It is not about the function itself, it is about how the function gets called. Commented Oct 16, 2014 at 2:00
  • 1
    You can use this structure, but you have to be very careful about the value of this. this is determined by how the function is called, not by how it is declared. Here, the value of this in your callback will determined by the .click() function and will likely not be what you want. You can use .bind() on your anonymous function that you pass if you want to control this yourself. Commented Oct 16, 2014 at 2:05
  • 1
    See this helpful section of the Javascript Zen Garden page for more details on how this works. Commented Oct 16, 2014 at 2:09

3 Answers 3

1

The problem is that there're two different contexts:

clickMe : function() {
    // here is one
    this.obj.click(function() {
        // here is another
        this.func();
    });
}

You can simple pass the function as parameter, like the following:

clickMe : function() {
    this.obj.click($.proxy(this.func, this));
}

http://jsfiddle.net/mp243wm6/2/

Sign up to request clarification or add additional context in comments.

5 Comments

Your second example won't have this set properly in func.
Awesome - that helps a ton! I don't know why I didn't think about passing it in like that, but it makes sense (from all the other comments - thank you) why [this] wouldn't mean the same thing within the click method.
@jfriend00 Ohhh sure, you're completely right. Fixed it.
@NicholausChipping Take a look the following, jsfiddle.net/mp243wm6/3. When you click the text.
Could also use: this.obj.click(this.func.bind(this));.
1

The problem:

Considering your code in the JSFiddle, you have:

onClick : function() {
    this.obj.click(function() {                
        this.func();
    });
},

As noted, you have different contexts going on here.

Consider the snippet this.obj.click(function() { this.func(); }). The first this here is a reference to the framework.events object. The second this here is a reference to whatever will be this when this function get called. In the case of your JSFiddle, when this.func gets called, this is actually the DOM object that represents the <div id="test">TEST</div> node. Since it doesn't have a func function, calling func() on it causes:

Uncaught TypeError: undefined is not a function

You have to understand the following: you have to pass the correct this in which you want the function func to be called.

The solution:

A couple of ways to make it work as you would like:

1. with bind

this.obj.click(this.func.bind(this));

This way, you are telling: "call my this.func function, but make sure that it will be called using the this that I am passing as a parameter". Vanilla JS, no $.proxy stuff.

JSFiddle

2. with a copy of the reference to the actual function

onClick : function() {
    var theFunctionReference = this.func;
    this.obj.click(function() {
        theFunctionReference();
    });
},

This way, you will not rely on the value of this outside of the context of the framework.events object.

JSFiddle

Comments

0

The issue is that this is not bound to the correct object. I would suggest you look into Function.bind() because that creates a function with this pointing to the right thing.

Comments

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.