内部onclick /事件函数内的变量范围

时间:2018-06-12 17:36:40

标签: javascript variables scope

这可能是一个模糊的问题(或者甚至之前已经回答,如果只是投了一个结果,我对正确方向上的观点感到满意),如果我只是阅读多了几次JavaScript的不同范围,我可能会更聪明,但看到我已经做了好几年,仍然对JavaScript范围的工作方式感到困惑 - 你们中的一些人可能有一个好的/正确的解释为什么下面的片段以它的方式工作:

(我知道有所涉及的范围/上下文,或者可能是可变的变量类型,但是无法弄清下面代码片段中的差异以及它为什么不合逻辑)

class test {
    constructor() {
        this.obj = document.createElement('div');
        let style = {'padding' : '5px'};

        this.obj.innerHTML = '<h3>Click the button:</h3>';
        for (let key in style) {
            this.obj.style[key] = style[key]; 
        }

        this.some_var = 55;
        this.update_state.call(this, 'test');
        this.update_state_working.call(this, 'test');
    }

    update_state(state) {
        if (state == 'test') {
            const frame = document.createElement('div');
            frame.innerHTML = '<input style="background-color: #00FF00;" type="submit" value="Not working" />';
            frame.onclick = function(event) {
                console.log('You pressed: ' + this.some_var);
            };
            this.obj.appendChild(frame);
        }
    }
}

这将失败,记录You pressed: undefined。对我来说,来自其他语言背景,有点令人困惑。

update_state(state) {
    let test_var = this.some_var;
    if (state == 'test') {
        const frame = document.createElement('div');
        frame.innerHTML = '<input style="background-color: #00FF00;" type="submit" value="Working" />';
        frame.onclick = function(event) {
            console.log('You pressed: ' + test_var);
        };
        this.obj.appendChild(frame);
    }
}

另一方面,这会起作用。 我假设它是因为test_varupdate_state中本地定义的块范围,有些如何被冻结到事件函数中?但我不明白为什么会有这种差异?我认为上下文是相同的,因为事件绑定到某个DOM对象或外部类范围/实例?

我发现What is the scope of variables in JavaScript?对实际示例中的不同范围有很好的解释,我认为根据示例#6可以访问this.some_var。这个问题scope of variable inside an event listener callback function - 暗示this.index应该可以在onclick函数中访问,对我而言 - 它不是吗?

解决此背景问题的最佳实践方法是什么?因为我很少看到有人通过let声明来解决它,但也许我错过了一些明显的东西?

我正在寻找解释(或描述pickle的资源)解释为什么这个本地声明的变量有效,为什么test实例的上下文可以&#39; t被用作变量源,如上面建议的链接,以及适当的解决方案可能是什么(如果没有通过块范围局部变量声明)。

JsFiddle:https://jsfiddle.net/2cbfhzt5/

0 个答案:

没有答案