【问题标题】:Uncaught TypeError: Cannot read property 'rank' of undefined未捕获的类型错误:无法读取未定义的属性“等级”
【发布时间】:2017-09-16 20:12:34
【问题描述】:

我刚开始学习 javascipt,在教程中间被这个错误难住了:

我正在尝试创建一个迷你游戏,我可以在其中翻转卡片并找到匹配项。

我有一个数组中的对象,并试图根据选择的卡片(对象)调用“等级”的特定值。

在控制台中运行代码给我一个错误: 未捕获的类型错误:无法读取未定义的属性“等级”。

Javascript:

console.log("Up and running");

var cards = [
{
    rank: "queen",
    suit: "hearts",
    cardImage: "images/queen-of-hearts.png"
},
{
    rank: "queen",
    suit: "diamonds",
    cardImage: "images/queen-of-diamonds.png"
},
{
    rank: "king",
    suit: "hearts",
    cardImage: "images/king-of-hearts.png"
},
{
    rank: "king",
    suit: "diamonds",
    cardImage: "images/king-of-diamonds.png"
}
];
var cardsInPlay = [];

var checkForMatch = function() {
    if (cardsInPlay[0] === cardsInPlay[1]) {
        alert("You found a match!");
    } else alert("Sorry, try again");
}
var flipCard = function(cardId) {
    console.log("User flipped " + cards[cardId].rank); 
    /*issue is with calling the rank*/
    console.log(cards[cardId].cardImage);
    console.log(cards[cardId].suit);
    cardsInPlay.push(cards[cardId].rank);
    if (cardsInPlay.length === 2) {
        checkForMatch();
    };
}

var createBoard = function() {
    for (var i = 0; i < cards.length; i ++) {
        var cardElement = document.createElement('img');
        cardElement.setAttribute("img", "images/back.png");
        cardElement.setAttribute("data-id", i);
        cardElement.addEventListener("click", flipCard());
        document.getElementById("game-board").appendChild(cardElement);
    }
}
createBoard();

flipCard(0);
flipCard(2);

我的错误是由于我使用card[cardId].rank从对象调用值的方式吗?

【问题讨论】:

  • flipcard函数需要cardId参数,当你在点击事件上调用flipcard时你没有传递任何参数,它变成了未定义的。

标签: javascript arrays javascript-objects


【解决方案1】:

您必须将函数引用传递给addEventListener(使用正确参数调用flipCard 的函数)。然后你会得到这个problem,你可以这样解决:

var createBoard = function() {
    for (var i = 0; i < cards.length; i ++) {
        var cardElement = document.createElement('img');
        cardElement.setAttribute("img", "images/back.png");
        cardElement.setAttribute("data-id", i);

        // ############################################# 

        (function(index) {
            cardElement.addEventListener("click", function() {
                flipCard(index);
            });
        })(i);

        // ############################################# 

        document.getElementById("game-board").appendChild(cardElement);
    }
}

或使用forEach 而不是for,这会让事情变得更简单:

var createBoard = function() {
    cards.forEach(function(card, i) {
        var cardElement = document.createElement('img');
        cardElement.setAttribute("img", "images/back.png");
        cardElement.setAttribute("data-id", i);

        // no need to wrap this in an immediately invoked function expression (as this whole code is wrapped in the callback of forEach)
        cardElement.addEventListener("click", function() {
            flipCard(i);
        });

        document.getElementById("game-board").appendChild(cardElement);
    }
}

【讨论】:

    【解决方案2】:

    尝试改变

    cardElement.addEventListener("click", flipCard());

    cardElement.addEventListener("click", function(){ flipCard(i); });

    更新开始

    cardElement.addEventListener("click", flipCard.bind(null, i));

    避免关闭cmets中提到的案例

    更新结束

    说明:调用addEventListener时,第二个参数必须是函数,但是你传递了函数flipCard的调用结果,返回undefined。

    您的代码中的另一个错误是您在没有参数的情况下调用它,而它期望 cardId 作为参数,而当它没有得到它时,它会从 cards 数组中获取未定义的元素

    【讨论】:

    【解决方案3】:

    更新一下

    cardElement.addEventListener("click", flipCard());

    收件人

    cardElement.addEventListener("click", function(e){ flipCard(e.target.dataset.id); });

    【讨论】:

      猜你喜欢
      • 2021-12-22
      • 2015-01-06
      • 2017-07-26
      • 2019-02-26
      • 2021-12-25
      • 1970-01-01
      • 2017-02-11
      相关资源
      最近更新 更多