Javascript 未捕获类型错误:无法读取属性';排名';未定义的 我刚刚开始学习JavaCIPT,我在教程的中间发现了这个错误:

Javascript 未捕获类型错误:无法读取属性';排名';未定义的 我刚刚开始学习JavaCIPT,我在教程的中间发现了这个错误:,javascript,arrays,javascript-objects,Javascript,Arrays,Javascript Objects,我正在尝试创建一个小型游戏,在那里我可以翻牌并找到匹配的东西 我有一个数组中的对象,并且根据选择的卡(对象)尝试调用特定的“秩”值 在console中运行代码时出现错误: 未捕获的TypeError:无法读取未定义的属性“rank” Javascript: console.log("Up and running"); var cards = [ { rank: "queen", suit: "hearts", cardImage: "images/queen-of-he

我正在尝试创建一个小型游戏,在那里我可以翻牌并找到匹配的东西

我有一个数组中的对象,并且根据选择的卡(对象)尝试调用特定的“秩”值

在console中运行代码时出现错误: 未捕获的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);
console.log(“启动并运行”);
var卡=[
{
等级:“女王”,
西装:“红心”,
CardMage:“图像/红心皇后.png”
},
{
等级:“女王”,
西装:“钻石”,
cardImage:“图像/钻石女王.png”
},
{
等级:“国王”,
西装:“红心”,
CardMage:“图像/红心之王.png”
},
{
等级:“国王”,
西装:“钻石”,
cardImage:“图像/钻石之王.png”
}
];
var cardsInPlay=[];
var checkForMatch=函数(){
if(cardsInPlay[0]==cardsInPlay[1]){
警告(“您找到了匹配项!”);
}else警报(“对不起,再试一次”);
}
var flipCard=功能(cardId){
console.log(“用户翻转”+卡片[cardd].rank);
/*问题是如何称呼军衔*/
console.log(卡片[cardId].cardImage);
console.log(卡片[cardd].suit);
cardsInPlay.push(卡片[cardd].rank);
如果(cardsInPlay.length==2){
checkForMatch();
};
}
var createBoard=函数(){
对于(变量i=0;i
我的错误是由于我使用cards[cardId].rank调用对象值的方式造成的吗?

尝试更改

cardElement.addEventListener(“单击”,flipCard())

cardElement.addEventListener(“单击”,函数(){flipCard(i);})

更新开始

cardElement.addEventListener(“单击”,flipCard.bind(null,i))

为了避免评论中提到的结案

更新结束

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


代码中的另一个错误是,您调用它时没有参数,而它期望
cardd
作为参数,当它没有得到参数时,它从
cards
数组中获取未定义的元素您必须将函数引用传递给
addEventListener
(一个使用正确参数调用
flipCard
的函数)。然后您将得到如下解决方法:

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);
    }
}
只是更新

cardElement.addEventListener(“单击”,flipCard());


cardElement.addEventListener(“单击”,函数(e){flipCard(e.target.dataset.id);})

flipCard函数需要一个cardId参数,当您在单击事件上调用
flipCard
时,您不会传递任何参数,并且它会变得未定义。不要忘记这一点:!
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);
    }
}