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

question-closed Javascript - dostęp do własności obiektu

VPS Starter Arubacloud
+1 głos
277 wizyt
pytanie zadane 16 marca 2021 w JavaScript przez Author[] Gaduła (3,130 p.)
zamknięte 16 marca 2021 przez Author[]

Mam pewną funkcję która przyjmuje 3 argumenty: 

  1. obiekt
  2. tablicę lub zmienną typu string
  3. dowolną wartość

Funkcja miała za zadanie zmienić wartość parametrów obiektu których nazwy znajdują się w argumencie 2

Jedyne rozwiązanie które działa wykorzystuje eval:

function bad(object, arg, new_value)
{
if (object==null || arg==null)
return false;

let command="object";

if(Array.isArray(arg))
{
arg.forEach((value)=>{
command+='['+value+']';
})
command+='='+new_value;
eval(command) /
}
else
{
object[arg]=new_value;
}
return true;
}

Czy da się zrobić coś takiego bez eval?

komentarz zamknięcia: Udało się rozwiązać problem

1 odpowiedź

+3 głosów
odpowiedź 16 marca 2021 przez Comandeer Guru (599,730 p.)
wybrane 16 marca 2021 przez Author[]
 
Najlepsza

Da się, wystarczy podstawić zmienną do nazwy własności: obj[ zmienna ] = wartosc;

komentarz 16 marca 2021 przez Author[] Gaduła (3,130 p.)

To wiem, wykorzystałem to w rozwiązaniu z eval, jednak nie mam pojęcia jak dostać się do obiektu zagnieżdżonego, którego stopnia zagnieżdżenia oraz własności wstępnie nie znam - dostają je od użytkownika. Przykład tu:

let obj={
example: "ssdas",
example1: {
     example2: "sdsadas"
},
example3: {
     example4: {
     example5: {}
}
}
}

mam tablicę w której przechowuję nazwę właściwości obiektu:

let arr=[example3, example4, example5]

Mając ją chcę się dostać do obiektu w ten sposób:

obj[arr[0]][arr[1]][arr[2]]="coś tam"

jednak nie znam długości tej tablicy dopóki jej nie dostanę

komentarz 16 marca 2021 przez Comandeer Guru (599,730 p.)

A, to najsensowniej jest to zrobić rekurencyjnie/iteracyjnie IMO. Coś typu:

  1. Niech zmienna current będzie naszym obiektem.
  2. Weź pierwszy element z tablicy z kluczami i zapisz do zmiennej key.
  3. Pobierz do zmiennej current obiekt current[ key ].
  4. Jeśli wciąż są elementy w tablicy z kluczami, przejdź do punktu 2. Jeśli tablica jest pusta, zwróć wartość current.
komentarz 16 marca 2021 przez Author[] Gaduła (3,130 p.)
Czy zadziała to do przypisania wartości?
komentarz 16 marca 2021 przez Comandeer Guru (599,730 p.)

Tak, z tym, że trzeba lekko zmodyfikować algorytm (zwrócić wartość current, gdy zostanie jeden element tablicy i wtedy zrobić przypisanie). Coś typu:

const obj = {
	a: {
		b: {
			c: {
				d: null
			}
		}
	},
	e: null
};

changeValue( obj, [ 'a', 'b', 'c', 'd' ], 'newValue' );
changeValue( obj, 'e', 'WHATEVER' );
console.log( obj );

function changeValue( obj, keys, newValue ) {
	if ( !Array.isArray( keys ) ) {
		keys = [ keys ];
	}

	let current = obj;

	while ( keys.length > 1 ) {
		current = current[ keys.shift() ];
	}

	current[ keys.shift() ] = newValue;
}

 

komentarz 16 marca 2021 przez Author[] Gaduła (3,130 p.)

Kod działa świetnie jednak mam jeszcze jedno pytanie. Próbowałem wykryć gdyby użytkownik przekazał do funkcji obiekt np taki:

let obj={}

I jako 2 parametr dał tablicę:

["example1", "example2"]

Wygeneruje to oczywiście błąd bo nie można znaleźć parametru example2 z obj["example1"]. Chciałbym jednak żeby program tworzył pusty obiekt (przykład wykorzystujący poprzednie dane wejściowe):

Wyjście:

{
    example1: {example2: "jakaś wartość"}
} 

Próbowałem to zrobić w ten sposób:

function changeValue( obj, keys, newValue ) {
    if ( !Array.isArray( keys ) ) {
        keys = [ keys ];
    }
 
    let current = obj;
 
    while ( keys.length > 1 ) {
        current = current[ keys.shift() ];
        if (current==undefined)
        {
               current={};
        }
    }
 
    current[ keys.shift() ] = newValue;
}

Niestety zamiast tworzyć obiekt w obiekcie funkcja zwraca pusty obiekt

komentarz 16 marca 2021 przez Comandeer Guru (599,730 p.)

Musiałbyś zrobić to inaczej. Raczej coś typu:

while ( keys.length > 1 ) {
		const key = keys.shift();

		if ( current[ key ] === undefined ) {
			current[ key ] = {};
		}
		
		current = current[ key ];
	}

 

komentarz 16 marca 2021 przez Author[] Gaduła (3,130 p.)
Wszystko działa, dziękuję za pomoc!

Podobne pytania

+1 głos
1 odpowiedź 213 wizyt
pytanie zadane 16 lutego 2022 w JavaScript przez poldeeek Mądrala (5,980 p.)
0 głosów
1 odpowiedź 110 wizyt
pytanie zadane 14 grudnia 2019 w JavaScript przez VGB Początkujący (370 p.)
0 głosów
0 odpowiedzi 160 wizyt
pytanie zadane 17 czerwca 2020 w JavaScript przez Uwaciusz Nowicjusz (140 p.)

92,452 zapytań

141,262 odpowiedzi

319,080 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!

...