javascript - `this.some_property` 在匿名回调函数中变为未定义

标签 javascript callback closures anonymous-function

所以我不太明白为什么变量 this.tasks 在我的目标对象中的添加事件监听器中变得未定义。我觉得它可能与异步编程有关(我仍然不完全理解)。抱歉,我是一个 JS 菜鸟,但如果你们能向我解释我做错了什么,以及什么可能是更好的解决方案,那就太棒了!谢谢。

function Goal(name) {
        this.gDiv =  document.createElement('div');
        this.name = name || "goal";
        this.tasks = document.createElement('ul');
        //Sets the styling and content and adds it to the parent element
        this.initialize = function() {
            this.gDiv.className = "default";
            this.gDiv.setAttribute("id", this.name);
            this.gDiv.innerHTML = this.name;
            elem.appendChild(this.gDiv);

            this.gDiv.parentNode.insertBefore(this.tasks, this.gDiv.nextSibling);
            this.tasks.style.display = "none";


        };  
        //Creates a list underneath the a dive associated with the Goal object
        this.addTask = function(task) {
            var newLi = document.createElement('li');
                newLi.innerHTML = task;
                this.tasks.appendChild(newLi);
        };

        this.gDiv.addEventListener('click', function(){
            alert(this.tasks);              
        });

    }

谢谢大家!你们都回答了我的问题!有一段时间我一直在摸不着头脑。感谢你们所有人!

最佳答案

当您输入匿名闭包时范围会发生变化并且“this”会发生变化。你可以通过做来破解它

var self = this;

然后用 self 代替这个(例如):

function Goal(name) {
    var self = this;

    /* ... */

    this.gDiv.addEventListener('click', function(){
        alert(self.tasks);              
    });

如果您使用的是 jQuery,您可以做一些更好的事情:

this.gDiv.addEventListener('click', $.proxy(function() {
    alert(this.tasks);
 }, this));

两种方式都可以。

编辑:在 ES6 中,可以使用箭头函数代替,因为它们不绑定(bind)自己的“this”,因此它变得更加简单:

this.gDiv.addEventListener('click', () => {
    alert(this.tasks);
 });

关于javascript - `this.some_property` 在匿名回调函数中变为未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21769460/

相关文章:

rust - 从与就地定义不一致的函数返回闭包

函数内部的Javascript闭包不是 "remember",而是环境

javascript - AngularJS - 表的嵌套 ng-repeat

javascript - 如果一个函数在另一个函数内部执行,它会立即符合回调函数的条件吗?

javascript - 如何将现有回调 API 转换为 Promise?

javascript - Node.js:异步回调 vs 同步回调 vs process.nextTick vs setTimeout

gradle - 如何将任务扩展对象传递给 Gradle 中的闭包?

javascript - Google Maps API - 对国家/地区进行地理编码,然后在点击时放大到国家/地区的边界

鼠标指针坐标上的javascript

javascript - 数组排序: Alphabetical and Numerically