• 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
226 wizyt
pytanie zadane 28 lipca 2021 w JavaScript przez Doge Gaduła (3,320 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 (269,120 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,320 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 (269,120 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 (251,210 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 (251,210 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 631 wizyt
0 głosów
1 odpowiedź 1,458 wizyt
pytanie zadane 9 maja 2018 w JavaScript przez Regmar Nowicjusz (120 p.)
0 głosów
1 odpowiedź 205 wizyt
pytanie zadane 15 kwietnia 2018 w JavaScript przez pawełrichert Nowicjusz (120 p.)

92,453 zapytań

141,262 odpowiedzi

319,088 komentarzy

61,854 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.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...