Frage

I thought I understood how javascript scope worked until now. This is what I have

function MFCommentsHandler(node, type, item) {
    this.get = function(returnType){
        ...
    }

    function getButton(){
        var button = document.createElement('button'),
            get = this.get;
        button.innerHTML = 'Load more comments';
        button.onclick = function(){
            console.log(get);
            get('html');
        }
        return button;
    }

}

I use inner functions to append the element generated by getButton to the document, but when I click it I get get is not a function. Why is get undefined inside of the onclick function?

War es hilfreich?

Lösung

this depends only on how you call a function. It can be implicit, but in your case, you lost the context. You need to cache this in the upper scope:

function MFCommentsHandler(node, type, item) {
    var self = this;
    this.get = function(returnType){
        ...
    }
    function getButton(){
        self.get(); // cached reference
        ...
    }
}

Or you can explicitly pass the context when you call getButton:

function MFCommentsHandler(node, type, item) {
    this.get = function(returnType){
        ...
    }
    function getButton(){
        this.get();
        ...
    }
    getButton.call(this); // explicit context
    ...

Andere Tipps

The referant of this changes with context. Try this instead:

function MFCommentsHandler(node, type, item) {
    var get = function(returnType){
        ...
    }

    function getButton(){
        var button = document.createElement('button');
        button.innerHTML = 'Load more comments';
        button.onclick = function(){
            console.log(get);
            get('html');
        }
        return button;
    }

}

The getButton() function you defined inside the MFCommentsHandler() function you defined is a closure. Closures have access to the variables and arguments (but not the arguments object) of their outer function. They however, do not have access to the this value of their outer function. To have access to this value, just store a reference of it in a variable so it can be accessed from the inner function.

function MFCommentsHandler(node, type, item) {
    var that = this; //reference to the invocation context
    //that can be accessed anywhere within this function

    this.get = function(returnType){
        ...
    }

    function getButton(){
        ...
        that.get('html');
    }

}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top