未捕获的TypeError:无法读取未定义的属性“rank”

时间:2017-04-20 09:20:56

标签: javascript arrays javascript-objects

我刚刚开始学习javascipt并且在教程中遇到了这个错误:

我正在尝试创建各种各样的迷你游戏,我会翻卡并找到匹配。

我有一个数组中的对象,我试图根据选择的卡(对象)来调用'rank'的特定值。

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

使用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);

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

3 个答案:

答案 0 :(得分:0)

尝试更改

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

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

更新开始

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

避免关闭评论中提到的案例

更新结束

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

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

答案 1 :(得分:0)

您必须将函数引用传递给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 :(得分:0)

只需更新

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

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