Javascript - 错误...不是闭包内的函数

标签 javascript object

在 for 循环中注释为:

// Iterate over the array and append each element as li

...有一个闭包,如果我只是把它工作得很好 console.log(标签[x]); 这表明关闭按预期进行。但是,当我放置闭包应包含的实际代码时,即。 this.displayImg(标签[x]);它会抛出一个错误。当我点击 li 时,我得到:

Uncaught TypeError: this.displayImg is not a function
(anonymous function) @ script.js:49

请告知我如何从该位置访问 this.displayImg。

var myGallery = (function () {
    var s;

    return {
        settings: {
            data: JSON.parse(data),
            filter: document.getElementById("filter"),
            gallery: document.getElementById("gallery")
        },
        init: function () {
            // kick things off
            s = this.settings;
            // By default, call the fillImages function with 'all' tag
            this.createFilters("all");
        },
        createFilters: function (tag) {
            // Load the image data
            // I made imgs global as I couldn't access it from displayImg
            imgs = this.settings.data.images;

            // Get image tags and generate a tag array
            var tags = ["all"];

            for (var i = 0; i < Object.keys(imgs).length; i++) {
                // Check if a tag is already in tags
                if (tags.indexOf(imgs[i].tag) > -1) {
                    // Yes, it is, so don't add it
                } else {
                    // No, it isn't, so add it to 'tags'
                    tags.push(imgs[i].tag);
                }
            }
            // Create an unordered list, assign a class to it and append to filter
            var ul = document.createElement('ul');
            ul.classList.add("ul-bare");
            this.settings.filter.appendChild(ul);

            // Iterate over the array and append each element as li
            for (var i = 0; i < tags.length; i++) {
                var li = document.createElement('li');
                ul.appendChild(li);
                li.innerHTML = tags[i];
                li.onclick = (function (x) {
                    return function () {
                        console.log(tags[x]);
                        this.displayImg(tags[x]);
                    };
                })(i);
            }
        },
        displayImg: function (filter) {
            // Add images to #gallery
            for (var i = 0; i < Object.keys(imgs).length; i++) {
                var div = document.createElement("img");
                // If the tage is 'all', display all images
                if (filter === "all") {
                    div.src = imgs[i].src;
                    this.settings.gallery.appendChild(div);
                } else {
                    // Display only images of certain category (tag argument)
                    if (imgs[i].tag === filter) {
                        div.src = imgs[i].src;
                        this.settings.gallery.appendChild(div);
                    }
                }
            }
        }
    };
})();

myGallery.init();

谢谢

最佳答案

onclick 中,this 将是对被单击的 DOM 元素的引用,而不是 this 所指的 Hook 位置起来吧。

如果您想在设置处理程序时访问 this 引用的对象,请使用变量:

var thisObj = this;
for (...) {

...然后在处理程序中:

thisObj.displayImg(tags[x]);

尽管在本例中,由于您不需要 this 来引用处理程序,您可以使用 Function#bind 使其变得更加简单:

for (var i = 0; i < tags.length; i++) {
    var li = document.createElement('li');
    ul.appendChild(li);
    li.innerHTML = tags[i];
    li.onclick = function(x) {
        console.log(tags[x]);
        this.displayImg(tags[x]);
    }.bind(this, i);
}

Function#bind 返回一个新函数,调用该函数时,将使用特定的 this 值以及您提供的任何其他参数来调用原始函数 bind(后跟运行时收到的任何参数)。

<小时/>

旁注:您也可以只传递标签,而不是索引:

var thisObj = this;
for (var i = 0; i < tags.length; i++) {
    var li = document.createElement('li');
    ul.appendChild(li);
    li.innerHTML = tags[i];
    li.onclick = (function(tag) {
        return function() {
            console.log(tag);
            thisObj.displayImg(tag);
        };
    })(tags[i]);
}

for (var i = 0; i < tags.length; i++) {
    var li = document.createElement('li');
    ul.appendChild(li);
    li.innerHTML = tags[i];
    li.onclick = function(tag) {
        console.log(tag);
        this.displayImg(tag);
    }.bind(this, tags[i]);
}

关于Javascript - 错误...不是闭包内的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35239829/

相关文章:

Java 8 可选择在分层对象中进行 null 检查

javascript - 在 JavaScript 中引用具有数值的对象属性

javascript - 如何从 Django 中的模态表单更新单个字段?

javascript - 使用JS绑定(bind)onchange事件(语法错误)

javascript - 如何检测字符串 `article/page/inc/3/4` 在 `inc` 的最后第三个索引中有 `/` ?

java - 访问对象数组列表中的特定元素

java - 每次返回对象的相同实例

javascript - 如何在预览图像上叠加图像

javascript - jQuery(或其他javascript)以距视口(viewport)顶部固定距离堆叠div

java - 将数组值加载到类中