Не получается переприсвоить значение

Всем здравствуйте!!
Столкнулся в своём коде с ошибкой того что при присвоении document.queryselectorAll всё нормально. Но когда нужно присвоить null, то ничего не происходит, то есть остаётся всё так как и было.
Вот мой код:

//Make a function
function CardGame() {
    //Define variables
    this.cardDeck = 36;
    this.cardNumbers = [];
    this.cardBack = null;
    this.getCard = null;
    this.passButton = null;
    this.myScore = null;
    this.opponentScore = null;
    this.opponentCards = null;
    var myHand = 0;
    var opponentHand = 0;
    ///Start function
    this.start = function () {
        var that = this;
        //Write in array amount of cards from 1 to 36
        for (var i = 1; i < this.cardDeck; i++) {
            var x = this.cardNumbers.push(Math.floor(Math.random() * this.cardDeck));
            x = this.cardNumbers[i]
        };
        console.log(this.cardNumbers);
        //call function and transfer values
        uniq_fast(this.cardNumbers);
        //function which mix a values of arr in different order
        function uniq_fast(a) {
            var seen = {};
            var out = [];
            var len = a.length;
            var j = 1;
            for (var i = 1; i < len; i++) {
                var item = a[i];
                if (seen[item] !== 1) {
                    seen[item] = 1;
                    out[j++] = item;
                }
                if (out.length < 36) {
                    out.push(Math.floor(Math.random() * 36));
                }
            }
            for (var x = 1; x < out.length; x++) {
                var wrapper = document.getElementById('wrapper');
                wrapper.innerHTML = wrapper.innerHTML + '<div id = ' + out[x] + ' class=no-card ><img src=./img/back-size-of-card.jpg /></div>'
            }
        }
        //add listeners to their selectors
        this.cardBack = document.querySelectorAll('.no-card');
        console.log(this.cardBack);
        for (const cardBack of this.cardBack) {
            cardBack.addEventListener('click', function () {
                that.onCardClick();
            });
        };

        this.passButton = document.querySelector('#pass-card-button');
        this.passButton.addEventListener('click', function (e) {
            setInterval(that.onPassClick, 3000);
        });
    };
    //function when user click on deck and cards are turn around
    this.onCardClick = function () {
        this.myCardsBlock = document.querySelector('.my-cards-block');
        this.myScore = document.getElementById('my-score');
        this.getCard = document.querySelectorAll('.no-card');
        var cardId = this.getCard[this.getCard.length - 1].id;
        this.getCard[this.getCard.length - 1].innerHTML = '<img src = ./img/' + cardId + '.jpg />'
        this.getCard[this.getCard.length - 1].className = 'my-card';
        this.myCardsBlock.append(this.getCard[this.getCard.length - 1]);
        var number = orderCardIds(cardId);
        myHand = myHand + number;
        this.myScore.innerHTML = myHand;
        if (myHand == 21) {
            alert('You are real Black Jack :)');
            this.startNewGame()
        } else if (myHand > 21) {
            alert('You lose? you have above 21 :(');
            this.startNewGame()
        }
    };
    //function when user click on pass and opponent make a move
    this.onPassClick = function () {
        this.opponentsCardsBlock = document.querySelector('.opponent-cards-block');
        this.opponentScore = document.getElementById('opponent-score');
        this.getCard = document.querySelectorAll('.no-card');
        var cardId = this.getCard[this.getCard.length - 1].id;
        this.getCard[this.getCard.length - 1].innerHTML = '<img src = ./img/' + cardId + '.jpg />'
        this.getCard[this.getCard.length - 1].className = 'opponent-card';
        this.opponentsCardsBlock.append(this.getCard[this.getCard.length - 1]);
        var number = orderCardIds(cardId);
        opponentHand = opponentHand + number;
        this.opponentScore.innerHTML = opponentHand;
        if (opponentHand == 21) {
            alert('You have beaten');
        } else if (opponentHand > 21) {
            alert('You are real Monster');
        }
    };
    //function that returns cardId for another functions
    orderCardIds = function (cardId) {
        if (cardId == '1' || cardId == '2' || cardId == '3' || cardId == '4') {
            cardId = 6;
        } else if (cardId == '5' || cardId == '6' || cardId == '7' || cardId == '8') {
            cardId = 7;
        } else if (cardId == '9' || cardId == '10' || cardId == '11' || cardId == '12') {
            cardId = 8;
        } else if (cardId == '13' || cardId == '14' || cardId == '15' || cardId == '16') {
            cardId = 9;
        } else if (cardId == '17' || cardId == '18' || cardId == '19' || cardId == '20') {
            cardId = 10;
        } else if (cardId == '21' || cardId == '22' || cardId == '23' || cardId == '24') {
            cardId = 2;
        } else if (cardId == '25' || cardId == '26' || cardId == '27' || cardId == '28') {
            cardId = 3;
        } else if (cardId == '29' || cardId == '30' || cardId == '31' || cardId == '32') {
            cardId = 4;
        } else if (cardId == '33' || cardId == '34' || cardId == '35' || cardId == '36') {
            cardId = 11;
        }
        return cardId;
    };
    this.startNewGame = function () {
        this.cardBack = null;
        new CardGame().start();
    }
}

var cardGame1 = new CardGame();
cardGame1.start();

Присвоение идёт к this.cardBack = document.querySelectorAll('.no-card');
Ожидается при условии

            alert('You are real Black Jack :)');
            this.startNewGame()
        }

вызвать функцию которая будет выполнять следующие действия:

this.startNewGame = function () {
        this.cardBack = null;
        new CardGame().start();
 },

но при присвоении null ничего не происходит и в следующей функции this.cardBack будет равняться не 36 а 72, то есть добавит элементы к предыдущей функции
Помогите пожалуйста

я верно понимаю что ты ожидаешь что это действие отменит обработчики событий навешанные в этом месте?

cardBack.addEventListener('click', function () {
    that.onCardClick();
});

По логике работы js и DOM ничего и не должно происходить. Обнуление переменной не ведет к удалению элементов из DOM-а страницы или убиранию обработчиков с них.

new CardGame().start(); создаст новый инстанc CardGame, перезапишет innerHTML игрового поля, но в памяти браузера останутся инстанс предыдущего CardGame, ссылки на предыдущие DOM узлы и обработчики на них, а так же останется запущенный интервал в довесок к новому созданному.

Бонусом ко всем проблемам, при таком запуске setInterval(that.onPassClick, 3000); this при запуске функции будет совсем не инстансом CardGame.


В целом код имеет кучу проблем (мы еще не обсудили последствия применения innerHTML, например) и чем больше ты будешь пытаться его “поправить” код или строить поверх него, тем больше будет вылазить проблем. Я предлагаю, если время-желание позволяет, обсудить в отдельной теме как лучше смоделировать задачу которую ты пытаешься решить. Для этого мне нужно знать описание задачи и ограничения.

Сам для себя поставил задачу сделать игру в 21(BlackJack) на js. То есть с начала должна составляться колода, после она перемешивается в разный порядок и создается картинка обратной стороны карты к каждому диву, должны выводится очки свои и соперника. После когда на обратную сторону карты в колоде нажимают срабатывает обработчик который вызывает функцию что сменяет класс, ссылку картинки карты и введёт счет, также сверяет счёт, что когда будет ровно 21 то выводит сообщение или когда больше 21 выводит другое сообщение. Когда игрок решит нажать пасс тогда сработает обработчик событий которой будет повешан таймаут каждые 3 секунды на другую функцию и если эта функция набрала ровно 21 то победил соперник и выводится сообщение, но если больше 21 то соперник проиграл. И также хотелось сделать раунды чтобы если кто- то победил очко засчитывалось одному из игроков.
Вот такую кашу заварил )

1 лайк

Я правильно понимаю что соперники играют за одним компьютером по очереди? Или игра идет против “компьютера” который сам решает брать еще или пасовать?

В целом идея понятна. Я подумаю над тем как это смоделировать и отпишусь.

Против компьютера игра

Можете пожалуйста описать какие недостатки моего кодинга так как это первый раз попытка написать что то на js

зачем там this
var
else elseif ||
querySelector/getElementById
alert

метод оркестр
myHand = myHand + number; откудато прилетело myHand
и orderCardIds
j это клюшка?
нужна большая расческа

Исправил код и сократил повторение теперь всё делается с помощью одной функции, код выглядит теперь так:
//Make a function
function CardGame() {
//Define variables
this.cardDeck = 36;
this.cardNumbers = [];
this.cardBack = null;
this.getCard = null;
this.passButton = null;
this.myScore = null;
this.opponentScore = null;
this.opponentCards = null;
this.myHand = null;
this.opponentHand = null;
this.cardId = null;
this.cardsBlock = null;
this.score = null;
this.hand = null;
this.orderCardIds = null;
///Start function
this.start = function () {
var that = this;
//Write in array amount of cards from 1 to 36
for (var i = 1; i < this.cardDeck; i++) {
var x = this.cardNumbers.push(Math.floor(Math.random() * this.cardDeck));
x = this.cardNumbers[i]
};
console.log(this.cardNumbers);
//call function and transfer values
uniq_fast(this.cardNumbers);
//function which mix a values of arr in different order
function uniq_fast(a) {
var seen = {};
var out = [];
var len = a.length;
var j = 1;
for (var i = 1; i < len; i++) {
var item = a[i];
if (seen[item] !== 1) {
seen[item] = 1;
out[j++] = item;
}
if (out.length < 36) {
out.push(Math.floor(Math.random() * 36));
}
}
for (var x = 1; x < out.length; x++) {
var wrapper = document.querySelector(‘#wrapper’);
wrapper.innerHTML = wrapper.innerHTML + ‘


}
}
//add listeners to their selectors
this.cardBack = document.querySelectorAll(‘.no-card’);
console.log(this.cardBack);
for (const cardBack of this.cardBack) {
cardBack.addEventListener(‘click’, function (e) {
that.eventClick(‘my-cards-block’, ‘my-score’, ‘my-card’);
});
};

    this.passButton = document.querySelector('#pass-card-button');
    this.passButton.addEventListener('click', function (e) {
        setInterval(that.eventClick, 3000, 'opponent-cards-block', 'opponent-score', 'opponent-card');
    });
};
this.eventClick = function(cardsBlockClass,scoreId,card){
    this.cardsBlock = document.querySelector('.'+cardsBlockClass);
    this.score = document.querySelector('#'+scoreId);
    this.getCard = document.querySelectorAll('.no-card');
    this.cardId = this.getCard[this.getCard.length - 1].id;
    this.getCard[this.getCard.length - 1].innerHTML = '<img src = ./img/' + this.cardId + '.jpg />'
    this.getCard[this.getCard.length - 1].className = card;
    this.cardsBlock.append(this.getCard[this.getCard.length - 1]);
    var number = this.orderCardIds(this.cardId);
    this.hand = this.hand + number;
    this.score.innerHTML = this.hand;
    if (this.hand == 21) {
        alert('You are real Black Jack :)');
        this.startNewGame()
    } else if (this.hand > 21) {
        alert('You lose? you have above 21 :(');
        this.startNewGame()
    }
}
//function that returns cardId for another functions
this.orderCardIds = function (cardId) {
    if (cardId == '1' || cardId == '2' || cardId == '3' || cardId == '4') {
        cardId = 6;
    } else if (cardId == '5' || cardId == '6' || cardId == '7' || cardId == '8') {
        cardId = 7;
    } else if (cardId == '9' || cardId == '10' || cardId == '11' || cardId == '12') {
        cardId = 8;
    } else if (cardId == '13' || cardId == '14' || cardId == '15' || cardId == '16') {
        cardId = 9;
    } else if (cardId == '17' || cardId == '18' || cardId == '19' || cardId == '20') {
        cardId = 10;
    } else if (cardId == '21' || cardId == '22' || cardId == '23' || cardId == '24') {
        cardId = 2;
    } else if (cardId == '25' || cardId == '26' || cardId == '27' || cardId == '28') {
        cardId = 3;
    } else if (cardId == '29' || cardId == '30' || cardId == '31' || cardId == '32') {
        cardId = 4;
    } else if (cardId == '33' || cardId == '34' || cardId == '35' || cardId == '36') {
        cardId = 11;
    }
    return cardId;
};
this.startNewGame = function () {
    new CardGame().start();
}

}

var cardGame1 = new CardGame();
cardGame1.start();
Столкнулся с ошибкой Uncaught TypeError: this.orderCardIds is not a function
То есть при нажатии на кнопку пасс срабатывает событие которое вызывает функцию для определения номера - this.orderCardIds, но пишет что это не функция в чем проблема разобраться не могу