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

this nie wskazuje na to co chce

VPS Starter Arubacloud
0 głosów
306 wizyt
pytanie zadane 1 listopada 2017 w JavaScript przez Marchiew Dyskutant (7,690 p.)

Cześć, może głupie pytanie, ale nie mogę sobie poradzić. Mam coś takiego:

Array.prototype.count = function(a = null) {
    let e = [];

    if(a !== null) {
        ...
    }
    else {
        e = this.forEach(function(g) {
                this.count(g);

            // console.log(g);
        });

        return e;
    }
}

i niestety wyświetla mi komunikat, że "this.count nie jest funkcją" przy this.count(g) w forEachu.

Jak mogę to naprawić? Chce, żeby to this wskazywało na tablicę do której przypiszę tę metodę, a nie jej elementu "g" lub czegokolwiek innego.

komentarz 1 listopada 2017 przez ScriptyChris Mędrzec (190,190 p.)
komentarz 1 listopada 2017 przez Marchiew Dyskutant (7,690 p.)

Pierwsze this wskazuje na Array.prototype czyli tablice. Zgadza się.

Drugie this ma wartość "undefined" co by się zgadzało z tym co Comandeer napisał, że na nic nie wskazuje.

Więc jak się mogę dowołać do Array.prototype. Wymyśliłem tylko coś takiego. Działa, ale nie wiem czy to jest dobre:

Array.prototype.count = function(a = null) {
    let e = [];
    const el = this;
 
    if(a !== null) {
        ...
    }
    else {
        e = el.forEach(function(g) {
                console.log( el.count(g) );
        });
 
        return e;
    }
}

 

komentarz 1 listopada 2017 przez ScriptyChris Mędrzec (190,190 p.)

const el = this;

Sposób ten jest powszechny - najczęściej spotyka się nazywanie zmiennej self lub that (w miejsce Twojego el).

Możesz też zastosować call.

Albo po prostu wstawić w forEach arrow function

komentarz 1 listopada 2017 przez Marchiew Dyskutant (7,690 p.)
No widzisz :D Myślałem tyle czasu nad czymś co w świecie jest cały czas robione.
Jedynie co mnie cieszy to, że sam na to wpadłem. Twój link był był jedynie drobną podpowiedzią i zachętą, żebym pomyślał bardziej. Dzięki.

call nie ogarniam w ogóle tak samo jak bind, więc zostanę przy tym co już mam.

Przy okazji natrafiłem na http://jsfiddle.net/9wqj6xpq/7/ fajne cudo zrobiłeś :)
komentarz 2 listopada 2017 przez ScriptyChris Mędrzec (190,190 p.)

call nie ogarniam w ogóle tak samo jak bind 

Function.prototype.bind to metoda, która tworzy (ale nie wywołuje), na podstawie podanej funkcji, nową funkcję z ustalonym przez Ciebie wskaźnikiem this oraz przekazanymi parametrami. Metoda Function.prototype.call pozwala na wywołanie funkcji ze zmienionym this i ustalonymi przez Ciebie parametrami (podobnie jest w przypadku .apply, który w odróżnieniu od .call przyjmuje tablicę parametrów).

Przy okazji natrafiłem na

To była moja pierwsza "pełnoprawna" aplikacja front-endowa, a właściwie (z tego co widzę po kodzie) - jej kawałek. Całość, do oceny, zamieściłem w tym temacie. Radzę jednak nie sugerować się kodem tam zawartym, bo nie jest dobrej jakości (jak na "pierwsze kroki" przystało). :)

1
komentarz 4 listopada 2017 przez Marchiew Dyskutant (7,690 p.)

Ok :D

Jeszcze jedno pytanie mam, bo nie chcę dla takiej pierdoły nowego tematu tworzyć. Po poradzeniu sobie z this i po ukończeniu pisania okazało się, że nie jest tak pięknie jakbym zakładał. Cały zamysł tej funkcji jest taki:

(function() {
    "use strict";

    Array.prototype.count = function(a = null) {
        let e = [];
        const self = this;

        if(a !== null) {
            e = self.filter(function(b) {
                return b === a;
            });
            return e.length;
        }
        else {
			self.forEach(function(f) {
				if(e.count(f) < 1) {
                    e[f] = self.count(f);
                }
			});
			
			return e;
        }
    }
})();

(function() {
    "use strick";

    const arr = ["cos", "aha", "aha", "mleko", "cos", "aha"];

    document.getElementById("wynik").innerHTML =  arr.count("cos");
	
	const arr2 = arr.count();
	
	console.log(arr2);
	
	arr2.forEach(function(e) {
		console.log(this[e]);
	});
	
})();

Problemem jest gdy nie podaje elementu do szukania. Zwracana jest tablica która nie jest pusta a jednak jest.

Nie mogę jej iterować, bo jest pusta, a po konkretnym indexie wyszukuje co trzeba. Wiesz  jak mogę to naprawić? 2 dni myślę nad tym.

 

komentarz 4 listopada 2017 przez ScriptyChris Mędrzec (190,190 p.)

Namieszałeś :)

Metoda forEach nie działa, ponieważ, property length jest zerem. Stało się tak dlatego, że błędnie umieszczasz elementy w tablicy. W roli indeksów używasz stringów, a powinieneś użyć liczby - cytat z dokumentacji:

Arrays cannot use strings as element indexes (as in an associative array), but must use integers. Setting or accessing via non-integers using bracket notation (or dot notation) will not set or retrieve an element from the array list itself, but will set or access a variable associated with that array's object property collection. The array's object properties and list of array elements are separate, and the array's traversal and mutation operations cannot be applied to these named properties.

Czyli, gdy w tablicy umieszczasz jakąś wartość, ale nie przez prawidłowy (liczbowy) numer indeksu, to ta wartość zostanie ustawiona jako nienumerowalne property i własność length nie zostanie odpowiednio zwiększona (przez co metody z łańcucha prototype tablicy - nie wiem czy wszystkie - nie będą działać). Przemyśl strukturę danych i funkcjonalność jaką ma wykonywać metoda count oraz stwórz prawidłową strukturę danych.

Zauważyłem również literówkę przy drugim 'use strict' => masz "use strick";

komentarz 4 listopada 2017 przez Marchiew Dyskutant (7,690 p.)

No właśnie wiem, że namieszałem haha

Chciałbym utworzyć taką strukturę mniej więcej:

[
   0: ["cos": 2],
   1: ["aha": 3],
   2: ["mleko": 1]
]

Jeśli ma to sens oczywiście, ale na chwilę obecną na nic lepszego nie wpadłem. Kombinuję z pushem:

for(let i=0, j=self.length; i<j; ++i) {
                if(e.count(self[i]) < 1) {
                    e.push( self[i] );

                    console.log( self[i] + ": " + self.count(self[i]) );
                }
            }

i po wyświetleniu w pętli zgadza się:

Nie umiem tego przełożyć na strukturę, którą naskrobałem haha ale debil ze mnie. Biorę się za coś czego nie potrafię zrobić.

 

komentarz 4 listopada 2017 przez ScriptyChris Mędrzec (190,190 p.)
[
   0: ["cos": 2],
   1: ["aha": 3],
   2: ["mleko": 1]
]

Popełniasz ten sam błąd: ["cos": 2] to tablica z błędnym indeksem elementu - jeśli chcesz propertisy z kluczami jako string, to zamiast tablicy powinien być tu obiekt, czyli { "cos": 2 }. Możesz oczywiście iterować po tablicy (a konkretnie po jej propertisach - czyli własnościach, które posiadają obiekty w JavaScript), gdzie indeksami nie są liczby (do tego służy pętla for..in), ale to nie jest naturalne przeznaczenie tablic.

komentarz 4 listopada 2017 przez Marchiew Dyskutant (7,690 p.)

Kurde.

zostaje tylko coś takiego:

[
    0: [
        0: "cos",
        1: 2
    ],

    1: [
        0: "aha",
        1: 3
    ],

    2: [
        0: "mleko",
        1: 1
    ]
]
           

Burzy to mają koncepcję tego, żeby była możliwość posortowania jej alfabetycznie malejąco lub rosnąco albo od największej ilości powtórzeń lub najmniejszej. Trudno i tak jak to wyjdzie to będę zadowolony

EDIT: Można by było pokusić się o zwracanie obiektu, ale nie umiem na nich operować i chyba nie ma tak dużych możliwości jak z tablicami

1
komentarz 4 listopada 2017 przez ScriptyChris Mędrzec (190,190 p.)

Tablica obiektów będzie tutaj ok. Napisałem Ci przykładowy kod na sortowanie rosnące wg alfabetu lub liczby (ustalasz to przez parametr).

Przykładowa struktura:

var structure = [
    { 'cos': 2 },
    { 'aha': 3 },
    { 'mleko': 1 }
];

Funkcje sortujące (tzn. jedna sortuje, a druga rozpakowuje):

function sortStructure( structure, valueType ) { // parametr pierwszy to struktura w formie TABLICY, drugi parametr to typ w postaci stringa (nazywasz słownie "string" lub "number")
	const destructObject = destructByType( valueType ); // przekazujesz typ, otrzymujesz funkcję rozpakowującą z zapamiętanym typem

	return structure.sort( ( currentValue, nextValue ) => {
		const currentValueSortable = destructObject( currentValue ); // przekazujesz obiekt, otrzymujesz rozpakowany klucz lub wartość (w zależności czy chcesz alfabetycznie - klucz, czy numerycznie - wartość)
		const nextValueSortable = destructObject( nextValue ); // j.w.

		if ( currentValueSortable < nextValueSortable ) {
			return -1;
        } else if ( currentValueSortable > nextValueSortable ) {
			return 1;
        }

		return 0;		
    } );
}

function destructByType( type ) { // argumentem <type> powinno być słowne określenie typu wartości - "number", albo "string"
    return ( obj ) => {
        const key = Object.keys( obj )[ 0 ]; // jako, że w Twojej strukturze, obiekty mają jeden property, to pobiera jedyny klucz

        return type === 'string' ? key : obj[ key ]; // jeśli typem jest string, zwraca klucz obiektu, a jesli co innego (czyli np. number) to zwraca wartość
    }
}

Użycie:

sortStructure( structure, 'string' ); // struktura posortowana alfabetycznie
sortStructure( structure, 'number' ); // struktura posortowana numerycznie

Możesz podpiąć funkcję sortStructure pod Array.ptototype, żeby działało na każdej tablicy. Jako ćwiczenie, możesz doimplementować sortowanie malejące i ewentualnie jakieś inne typy danych :)

komentarz 4 listopada 2017 przez Marchiew Dyskutant (7,690 p.)
Takiej odpowiedzi to się nie spodziewałem. Żeś mnie zaskoczył. Dzięki wielkie za wszelkie wyjaśnienia, podpowiedzi i starania. Postaram się już nie pytać o pierdoły haha. Bardzo dużo mi i tak pomogłeś.

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

0 głosów
0 odpowiedzi 474 wizyt
0 głosów
3 odpowiedzi 389 wizyt
pytanie zadane 26 października 2018 w JavaScript przez turtelian Obywatel (1,760 p.)
+2 głosów
3 odpowiedzi 708 wizyt
pytanie zadane 4 czerwca 2015 w Java przez Dissio Mądrala (5,830 p.)

92,452 zapytań

141,262 odpowiedzi

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

...