Функция, вызываемая несколько раз внутри другого, вызывает ошибку TypeError: Невозможно прочитать свойство 'suit' из undefined
Я пытаюсь создать функцию, которая проверяет, находятся ли две колоды карт в одном порядке.
Я написал вспомогательную функцию cardEq, чтобы проверить, одинаковы ли две карты, и это работает. Это не работает в функции deckEq.
//Card Struct
//value 1 is ace, 11 is Jack, 12 is Queen, and 13 is King
function Card(suit, value, color){
this.suit = suit,
this.value = value,
this.color = color
}
//Check if two Cards are the same
function cardEq(card1, card2){
if(card1.suit === card2.suit
&& card1.value === card2.value
&& card1.color === card2.color){
return true;
} else {return false;}
}
//Check if two Decks/arrays of Cards are in the same order
function deckEq(deck1, deck2){
let i = 0;
let flag = false;
while (i < 53){
let x = deck1[i];
let y = deck2[i];
if(cardEq(x, y) === true){
flag = true;
i = i + 1;
} else {flag = false; break;}
}
return flag;
}
Я ожидал, что он вернет либо true, либо false, но вместо этого он выдаст ошибку: TypeError: Невозможно прочитать свойство 'suit' undefined в cardEq (repl:2:12) в deckEq (repl:7:8)
РЕДАКТИРОВАТЬ: я изменил (я < 53) в заявлении в то время как (я < 52). Спасибо за улов @Christopher и @traktor53. Я предполагаю, что проблема заключалась в том, что функция вызывала cardEq для элемента в массиве, который не существует (52-й). Так как это предназначено для сравнения колод, оно должно работать только с 51-м элементом (52-я карта).
2 ответа
Как предположил @Christopher, проблема заключается в проверке 53 карт в массиве из 52 карт с нулевой базой deckEq
, Измените оператор цикла while на
while (i < 52){
чтобы увидеть, как он работает правильно с колодой из 52 карт -
"use strict";
//Card Struct
//value 1 is ace, 11 is Jack, 12 is Queen, and 13 is King
function Card(suit, value, color){
this.suit = suit,
this.value = value,
this.color = color
}
//Check if two Cards are the same
function cardEq(card1, card2){
if(card1.suit === card2.suit
&& card1.value === card2.value
&& card1.color === card2.color){
return true;
} else {return false;}
}
//Check if two Decks/arrays of Cards are in the same order
function deckEq(deck1, deck2){
let i = 0;
let flag = false;
while (i < 52){
let x = deck1[i];
let y = deck2[i];
if(cardEq(x, y) === true){
flag = true;
i = i + 1;
} else {flag = false; break;}
}
return flag;
}
function createDeck(){
const deck = [];
const colors = ["black", "red", "red", "black"];
for( var i = 0; i < 52; ++i) {
var suite = Math.floor( i / 13);
var value = i % 13 + 1;
var color = colors[ suite];
deck.push( new Card( suite, value, color));
}
return deck;
}
let deck1 = createDeck();
let deck2 = createDeck();
console.log( deckEq( deck1, deck2)); // expect true
deck2[42] = deck2[0];
console.log( deckEq( deck1, deck2)); // expect false
Еще лучше использовать длину массива колоды, чтобы контролировать количество итераций цикла while, и проверить колоды одинаковой длины перед началом цикла.
this
внутри функции работает только тогда, когда функция используется в качестве " функции конструктора ", что требует new
экземпляр объекта, который создает функция конструктора. Это объект, который this
будет связывать, в противном случае, this
будет привязан к window
а также window
не имеет suit
имущество.
//Card Struct
//value 1 is ace, 11 is Jack, 12 is Queen, and 13 is King
function Card(suit, value, color){
this.suit = suit,
this.value = value,
this.color = color
}
//Check if two Cards are the same
function cardEq(card1, card2){
if(card1.suit === card2.suit
&& card1.value === card2.value
&& card1.color === card2.color){
return true;
} else {return false;}
}
//Check if two Decks/arrays of Cards are in the same order
function deckEq(deck1, deck2){
let ceq = new cardEq(x,y); // <-- Need an instance produces by the function
let i = 0;
let flag = false;
while (i < 53){
let x = deck1[i];
let y = deck2[i];
if(ceq === true){ // <-- Use the instance
flag = true;
i = i + 1;
} else {flag = false; break;}
}
return flag;
}