Почему работает функция Javascript без объявленного параметра?

#javascript #function #parameters

#javascript #функция #параметры

Вопрос:

Я пишу игру hangman. С помощью Google у меня есть функция проверки наличия буквы в слове, но я не понимаю, как, хотя я никогда не объявляю параметр «chosenLetter» моей функции, это может дать «chosenLetter» точное значение конкретной буквы, на которую я нажимаю. И как «getElementById (chosenLetter)» может выбрать именно ту букву, на которую я нажимаю, чтобы отключить кнопку. То же самое с функцией «guessedWord», где «буква» никогда не объявляется, но она выбирает букву для проверки в «угаданном» массиве

 let answer = '';
let maxWrong = 5;
let mistakes = 0;
let guessed = [];
let wordStatus = null;

function guessedWord() {
wordStatus = answer.split('').map(letter => (guessed.indexOf(letter) >= 0 ? letter : '_')).join('');

document.getElementById('word').innerHTML = wordStatus;}

function generateButtons() {
let buttonsHTML = 'abcdefghijklmnopqrstuvwxyz'.split('').map(letter => 
    `
    <button
        class = "btn"
        id = '`   letter   `'
        onClick = "handleGuess('`   letter   `')"
    >
    `   letter   `
    </button>
    `).join('');

    document.getElementById('alphabet').innerHTML = buttonsHTML;}

function handleGuess(chosenLetter) {
if (guessed.indexOf(chosenLetter) === -1) {
    guessed.push(chosenLetter)
} else {
    null;
} 

document.getElementById(chosenLetter).setAttribute('disabled', true);

if (answer.indexOf(chosenLetter) >= 0) {
    guessedWord();
    checkIfGameWon();
} else if (answer.indexOf(chosenLetter) === -1) {
    mistakes  ;
    updateMistakes();
    checkIfGameLost();
}}
  

Поскольку я новичок в javascript, я обычно пытаюсь понять, как возможно, что не объявленные параметры могут объявлять себя так конкретно? Я не знаю, задаю ли я неправильный вопрос, но это единственная вещь в коде, которую я не могу ни понять, ни объяснить

Комментарии:

1. Аргументы функции объявляются автоматически при вызове функции. Вы передаете значение в этой строке : onClick = "handleGuess('` letter `')" .

2. Примечание; вы используете шаблонные литералы как обычные строки. Это сводит на нет цель их использования, когда использование интерполяции гораздо более выгодно. Пример: `<button class="btn" id="${letter}">`

Ответ №1:

Сначала вам нужно прочитать эту документацию.

В нем говорится

Метод map() создает новый массив, заполненный результатами вызова предоставленной функции для каждого элемента в вызывающем массиве.

Если мы попытаемся разбить следующий оператор на отдельные операторы,

 wordStatus = answer.split('').map(letter => (guessed.indexOf(letter) >= 0 ? letter : '_')).join('');
  

Вы найдете,

 let splittedAnswer = answer.split(''); // This will split the answer string and crate an array with all the characters in answer.

const callbackFunction = (letter) => {
    return guessed.indexOf(letter) >= 0 ? letter : '_';
}
let newArray = splittedAnswer.map(callbackFunction);
let joinedString = newArray.join('');
  

Как вы можете видеть, вы объявляете функцию обратного вызова. Вы передаете эту функцию array.map() методу. Теперь метод array.map() вызовет функцию с 3 параметрами currentItemInTheArray, currentIndex, theSourceArray . Поскольку вы объявили только первый параметр в своей функции обратного вызова, т.е. currentElementInTheArray, вы получите первый параметр. Вы могли бы объявить свой массив обратного вызова следующим образом,

 const callbackFunction = (item, index, arr) => {
    console.log(item);
    console.log(index);
    console.log(arr);
}
  

И теперь, если вы вызываете

 [1,2,3].map(callbackFunction);
  

Вы получите следующий вывод,

 1 //currItem
0 //index
[1,2,3] //source array

2 //currItem
1 //index
[1,2,3] //source array

3 //currItem
2 //index
[1,2,3] //source array
  

Но вы делаете это встроенным, поэтому вы не следили. Надеюсь, теперь вам это понятно.

Комментарии:

1. Хорошо, похоже, я наткнулся на что-то более продвинутое, чем я собирался, хе-хе, так что в основном это работает так: когда я добавляю .map() , то, что автоматически добавит в скобки, это элемент, индекс и исходный массив. И если я добавлю функцию обратного вызова в поле элемента, моя буква параметра будет объявлена как каждый элемент в массиве? Что означает каждый элемент в answer.split?

2. ДА. Вы все правильно поняли. Метод map вызовет вашу функцию обратного вызова с каждым элементом исходного массива.

Ответ №2:

Вот как работают функции: вы передаете аргумент в качестве входных данных и для использования этого аргумента в своей функции используете параметры в определении функции, которые действуют как заполнители для вашего ввода, а затем вы можете использовать параметры в любом месте внутри вашей функции.

Пример: в функции guessedWord() вы используете функцию map, которая принимает функцию обратного вызова в качестве аргумента. Таким образом, рабочая буква на самом деле является параметром функции обратного вызова, а параметры не нуждаются в объявлении, они просто заполнители.

Ответ №3:

generateButtons собирается ли вставить в HTML-элемент «алфавит» что-то похожее на это:

     <button
        class = "btn"
        id = 'a'
        onClick = "handleGuess('a')"
    >
      a
    </button>
    <button
        class = "btn"
        id = 'b'
        onClick = "handleGuess('b')"
    >
      b
    </button>
    ...
  

Эти onClick обработчики будут функциями, которые передают различные буквы в качестве первого (и единственного) аргумента handleGuess .

handleGuess является ли функция, объявленная для приема одного параметра, который известен внутри функции как chosenLetter . Но когда вы вызываете ее, вам не нужно передавать ей переменную с именем chosenLetter . Javascript это не волнует. Вы могли бы передать ей переменную с именем foobar , и все было бы хорошо, или вы могли бы просто передать ей необработанное значение.

Для более простого примера предположим, что у нас была простая функция:

 function area (height, width) {
  return height * width
}
  

мы могли бы вызывать ее различными способами, в том числе:

 const height = 5;
const width = 8;

area (height, width) //=> 40

// or

const h = 6
const w = 7

area (h, w) //=> 42

// or

const rectangle = {
  height: 3,
  width: 10
}

area (rectangle.height, rectangle.width) //=> 30

// or simply

area (4, 9) //=> 36
  

Тот же принцип применим к handleGuess

Комментарии:

1. Верно, я полностью пропустил вызов функции handleGuess! Теперь это имеет смысл. Спасибо!

Ответ №4:

в JavaScript переменные, которые не объявляются, автоматически присваиваются глобальной области видимости

это простые слова, которые он объявит сам 🙂

в вашем случае происходит что-то другое

вы передаете букву в качестве параметра функции

 onClick = "handleGuess('`   letter   `')"
  

и вот почему это оживляет всю магию 🙂

то же самое относится и к свойству id

  id = '`   letter   `'
  

передавая информацию о том, на какую конкретную букву вы нажимаете, сделайте так, чтобы движок JavaScript знал, какая кнопка нажата, и именно так он узнает, какую букву вы выбрали и что ему нужно отключить

Комментарии:

1. Этот ответ просто запутывает проблему. Здесь нет ничего о необъявленных переменных. И в StackOverflow есть доска заданий. Не стесняйтесь использовать его. Но не используйте область вопросов и ответов для действий по поиску работы.