• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

błąd - Argument funkcji is not defined ???

VPS Starter Arubacloud
+1 głos
257 wizyt
pytanie zadane 28 lipca 2021 w JavaScript przez Doge Gaduła (3,420 p.)

Witam, otrzymuję błąd

Uncaught ReferenceError: achievement is not defined

kiedy wywołuję funkcję

open_modal_box_give_achievement_reward(1, achievement_i_array);
function open_modal_box_give_achievement_reward(achievement, achievement_i_array)

a następnie w tej funkcji wywołuję inną funkcję, której parametrami są parametry bieżącej funkcji:

give_achievement_reward(achievement, achievement_i_array);
function give_achievement_reward(achievement, achievement_i_array)

Błąd wyskakuje po wywołaniu drugiej funkcji. O co tutaj chodzi? Wcześniej wywoływałem funkcje przekazując argumenty z jednej na drugą i nic się nie działo.

Całość funkcji:

function open_modal_box_give_achievement_reward(achievement, achievement_i_array)
{
	const modal_box = document.querySelector(".modal-container");
	modal_box.style.display = "flex";
	
	var title = document.querySelector(".modal-container .box .title-bar");
	title.innerHTML = '<span class="title">You received a reward for achievement</span>';
	
	var content = document.querySelector(".modal-container .box .content");
	content.innerHTML = `<div class="divs"><button onclick="give_achievement_reward(achievement, achievement_i_array)">OK</button></div>`;
}
function give_achievement_reward(achievement, achievement_i_array)
{
	if_received_achievement_reward[achievement_i_array] = 1;
	if(selected_page.substring(0, selected_page.length-1) == 'achievements')
	{
		achievements(parseInt(selected_page.substr(selected_page.length-1, 1)));
	}
	switch(achievement)
	{
		case 1:
			coins += 1;
			break;
		case 2:
			coins += 2;
			break;
		case 3:
			coins += 3;
			break;
		case 4:
			coins += 4;
			break;
		case 5:
			coins += 5;
			break;
		case 6:
			coins += 6;
			break;
		case 7:
			coins += 7;
			break;
		case 8:
			coins += 8;
			break;
		case 9:
			coins += 9;
			break;
		case 10:
			coins += 10;
			break;
		case 11:
			coins += 11;
			break;
		case 12:
			coins += 12;
			break;
		case 13:
			coins += 13;
			break;
		case 14:
			coins += 14;
			break;
		case 15:
			coins += 15;
			break;
		case 16:
			coins += 16;
			break;
	}
	coins_update();
	close_modal_box();
}

wywołanie pierwszej funkcji odbywa się poprzez naciśnięcie:

text.setAttribute("onclick", "open_modal_box_give_achievement_reward(1, achievement_i_array)");

(switch w drugiej funkcji taki bezsensowny, ponieważ będę go jeszcze edytował, teraz jest tylko dla testu i przygotowany na później)

1 odpowiedź

+1 głos
odpowiedź 28 lipca 2021 przez Wiciorny Ekspert (275,640 p.)
wybrane 29 lipca 2021 przez Doge
 
Najlepsza

achievements - a gdzie taka zmienna jest zdefiniowana? U ciebie w kodzie jej nie widzę, widzę tylko definicje metody która przyjmuje argument o takiej nazwe. Dodatkowo w argumencie masz achievement 
przyczym argument funkcji to tylko "nazwa", może to być całkowicie inna nazwa, która jest używana na rzecz tej metody w jej ciele.

achievements(parseInt(selected_page.substr(selected_page.length-1, 1)));

achievements ( różnica w końcówce) tej funkcji też tutaj nie widzę.. pewnie jest globalna, ale generalnie z zamieszczonego kodu nie widzę samej deklaracji/definicji zmiennej achivement 

komentarz 29 lipca 2021 przez Doge Gaduła (3,420 p.)

Po zadeklarowaniu innych zmiennych globalnie i przypisaniu im wartości argumentów funkcji a następnie wywołaniu innej funkcji przy ich pomocy, teraz działa. Nie wiem dlaczego, ale po zadeklarowaniu lokalnie również to nie działało.

Działa:

function open_modal_box_give_achievement_reward(achievement, achievement_i_array)
{
	achievement_helpful = achievement; //globalna
	achievement_i_array_helpful = achievement_i_array; //globalna
	const modal_box = document.querySelector(".modal-container");
	modal_box.style.display = "flex";
	
	var title = document.querySelector(".modal-container .box .title-bar");
	title.innerHTML = '<span class="title">You received a reward for achievement</span>';
	
	var content = document.querySelector(".modal-container .box .content");
	content.innerHTML = `<div class="divs"><button onclick="give_achievement_reward(achievement_helpful, achievement_i_array_helpful)">OK</button></div>`; //wywołanie
}

Nie działa:

function open_modal_box_give_achievement_reward(achievement, achievement_i_array)
{
	var achievement_helpful = achievement; //lokalna
	var achievement_i_array_helpful = achievement_i_array; //lokalna
	const modal_box = document.querySelector(".modal-container");
	modal_box.style.display = "flex";
	
	var title = document.querySelector(".modal-container .box .title-bar");
	title.innerHTML = '<span class="title">You received a reward for achievement</span>';
	
	var content = document.querySelector(".modal-container .box .content");
	content.innerHTML = `<div class="divs"><button onclick="give_achievement_reward(achievement_helpful, achievement_i_array_helpful)">OK</button></div>`; //wywołanie
}

Dlaczego tak się dzieje, skoro używam tych zmiennych tylko wewnątrz funkcji wywołującej? Czy dostęp do zmiennej musi mieć również funkcja wywoływana z pomocą tej zmiennej?

1
komentarz 29 lipca 2021 przez Wiciorny Ekspert (275,640 p.)

lokalnie nie działa dlatego, że ty nie przekazujes zmiennej do funkcji -> zobacz jak ona jest napisana przekazujesz tutaj "tesktowo" musisz ją zapisac nie co inaczej 

`<button onclick="(${achievements})('${achievements_cos_tam}')">test</button>`

kożystasz z tamplate stringa, wiec źle przekazujesz zmienne do funkcji, nawet w samym zapisie tutaj widać że to jest jako tekst powinieneś to  zrobić na bazie konkatenacji 

'<input type="button" onClick="gotoNode(\'' + result.name + '\')" />'

dwa przykłady, bo u CIebie po prostu posyłasz to jako słowa.


Globalnie działa bo na stronie globalna zmienna jest czytaa przez funkcje, natomiast jeśli jest ona lokalnie to tylko w momencie tworzenia twojego "diva" są widoczne te zmienne więc tutaj posyłasz im tak naprawde teskt- który jest praktycznie undefined 

komentarz 1 sierpnia 2021 przez VBService Ekspert (255,440 p.)
edycja 1 sierpnia 2021 przez VBService

@Wiciorny, 

... nie przekazujes zmiennej do funkcji -> zobacz jak ona jest napisana przekazujesz tutaj "tesktowo" musisz ją zapisac nie co inaczej 

kożystasz z tamplate stringa, wiec źle przekazujesz zmienne do funkcji, nawet w samym zapisie tutaj widać że to jest jako tekst powinieneś to  zrobić na bazie konkatenacji 

dwa przykłady, bo u CIebie po prostu posyłasz to jako słowa.

 

podtrzymujesz te słowa  wink

<div class="container"></div>
<pre class="messages"></pre>
const container = document.querySelector('.container'),
       messages = document.querySelector('.messages');
   
const results = [
  { name:"result", value:1 }, 
  { name:"result", value:2 },
  { name:"result", value:3 }
];
   
let button_template_string = 'template string: \n',
    button_concatenate_strings = 'concatenate strings: \n';
   
results.forEach((result) => {
      button_template_string += `<button onclick="${result.name}('${result.value}')">test ${result.value}</button> \n`;
  button_concatenate_strings += '<button onclick="result(\'' + result.value + '\')">test ' + result.value + '</button> \n';
})
   
container.innerHTML = button_template_string + '<br><br>'
                    + button_concatenate_strings;

messages.textContent = `${button_template_string} \n`
                     + `${button_concatenate_strings} \n`;
   
function result(value) {
  messages.textContent += value + ' ';
}

nawet taki nietypowy (rzadko spotykany w tym kontekście) zapis "nazwy" funkcji: (nazwa)(value)

`<button onclick="(${result.name})('${result.value}')">

w js-ie zadziała. wink

komentarz 1 sierpnia 2021 przez VBService Ekspert (255,440 p.)
edycja 1 sierpnia 2021 przez VBService

@Wiciorny, 

nie przekazujes zmiennej do funkcji -> zobacz jak ona jest napisana przekazujesz tutaj "tesktowo" 

w pewnym sensie, masz rację, tylko przykład podany przez Ciebie nie obrazuje problemu

`<button onclick="(${achievements})('${achievements_cos_tam}')">test</button>`

ten zapis jest prawidłowy

 

const achievements = 'achievements_f', achievements_cos_tam = 'cos tam';

const a = `<button onclick="(${achievements})('${achievements_cos_tam}')">test</button>`;

console.log(a);
document.body.innerHTML = a;

function achievements_f(x) {
  console.log('funkcja achievements_f - ' + x);
}

 

kolega @Doge, zrobił błędy w zapisie swojego template string-a

content.innerHTML = `<div class="divs"><button onclick="give_achievement_reward(achievement_helpful, achievement_i_array_helpful)">OK</button></div>`;

 

nie zapisał prawidłowo zmiennych, zmienne w template string-u poprzedzone są znakiem $ (dolara) i są "zamknięte" w { } klamrowych nawiasach.

give_achievement_reward( ${achievement_helpful}, ${achievement_i_array_helpful} )

 

const achievements = 'achievements_f', achievements_cos_tam = 'cos tam';
 
const a = `<button onclick="(${achievements})('${achievements_cos_tam}')">test</button>`;
console.log(a);
document.body.innerHTML = a + '<br>';

const b = `<button onclick="(achievements)('achievements_cos_tam')">test</button>`;
console.log(b);
document.body.innerHTML += b + '<br>';

const c = `<button onclick="(achievements_f)('achievements_cos_tam')">test</button>`;
console.log(c);
document.body.innerHTML += c+ '<br>';

const d = `<button onclick="achievements_f(achievements_cos_tam)">test</button>`;
console.log(d);
document.body.innerHTML += d;
 
function achievements_f(x = 0) {
  console.log('funkcja achievements_f - ' + x);
}

 

BTW: kod "d" zwraca ciekawy wynik (na Chromie, nie testowałem na innych).

Podobne pytania

0 głosów
3 odpowiedzi 740 wizyt
0 głosów
1 odpowiedź 1,523 wizyt
pytanie zadane 9 maja 2018 w JavaScript przez Regmar Nowicjusz (120 p.)
0 głosów
1 odpowiedź 217 wizyt
pytanie zadane 15 kwietnia 2018 w JavaScript przez pawełrichert Nowicjusz (120 p.)

92,845 zapytań

141,784 odpowiedzi

320,859 komentarzy

62,178 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Wprowadzenie do ITsec, tom 2

Można już zamawiać tom 2 książki "Wprowadzenie do bezpieczeństwa IT" - będzie to około 650 stron wiedzy o ITsec (17 rozdziałów, 14 autorów, kolorowy druk).

Planowana premiera: 30.09.2024, zaś planowana wysyłka nastąpi w drugim tygodniu października 2024.

Warto preorderować, tym bardziej, iż mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy dodatkowe 15% zniżki! Dziękujemy zaprzyjaźnionej ekipie Sekuraka za kod dla naszej Społeczności!

...