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?

有帮助吗?

解决方案

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
    ...

其他提示

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');
    }

}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top