Skip to content

Latest commit

 

History

History
128 lines (96 loc) · 4.63 KB

File metadata and controls

128 lines (96 loc) · 4.63 KB

Konstruktorok

Csak úgy, mint minden más, a konstruktorok működése szintén különbözik a megszokottól. Itt minden függvényhívás amelyet a new kulcsszó előz meg, konstruktor hívásnak számít.

A this értéke a konstruktoron - hívott függvényen - belül az újonnan létrehozott objektumra mutat. Az új objektum prototípusa a konstruktor függvény prototípusával fog megegyezni.

Ha a konstruktor függvényben nincs return utasítás, akkor automatikusan a this értékével tér vissza - a létrehozott objektummal.

function Foo() {
    this.bla = 1;
}

Foo.prototype.test = function() {
    console.log(this.bla);
};

var test = new Foo();

A fenti kódban a Foo függvényt, mint konstruktort hívjuk meg, ami a test változóban egy új objektumot fog eredményezni. Ennek az objektumnak a prototípusa a Foo prototípusa lesz.

Trükkös ugyan, de ha mégis van return utasítás az éppen konstruált függvényben, akkor a függvény hívása az annak megfelelő értékkel fog visszatérni, de csak akkor, ha a visszatérített érték Objektum típusú.

function Bar() {
    return 2;
}
new Bar(); // ez egy új üres objektum lesz: {}, a 2 helyett

function Test() {
    this.value = 2;

    return {
        foo: 1
    };
}
new Test(); // ez a { foo: 1 } objektumot fogja eredményezni

Hogyha kihagyjuk a new kulcsszó használatát, a függvény nem egy új objektummal fog visszatérni.

function Foo() {
    this.bla = 1; // ez a globális objektumon állít
}
Foo(); // undefined

A this JavaScript beli működésének köszönhetően, még ha le is fut az előbbi kód, akkor a this helyére a globális objektumot képzeljük.

Gyárak (Factory-k)

Ahhoz, hogy teljesen el tudjuk hagyni a new kulcsszó használatát, a konstruktor függvény explicit értékkel kell visszatérjen.

function Bar() {
    var value = 1;
    return {
        method: function() {
            return value;
        }
    }
}
Bar.prototype = {
    foo: function() {}
};

new Bar();
Bar();

Mindkét Bar-ra történő hívásmód ugyanazt fogja eredményezni. Kapunk általuk egy újonnan létrehozott objektumot, amelynek lesz egy method nevű mezője, ami egyébiránt egy Closure.

Azt is érdekes itt megjegyezni, hogy a new Bar() hívás nem befolyásolja a visszatérített objektum prototípusát. Mivel a prototípus csak az újonnan létrehozott objektumon létezik, amit a Bar nem térít vissza (mivel egy explicit értéket ad vissza).

A fenti példában nincs funkcionális különbség aközött hogy kiírjuk-e a new varázsszót avagy nem.

Új objektumok létrehozása gyárakon keresztül

Gyakran bevett módszer egy projetkben, hogy a new varázsszó használatát teljesen elhagyjuk, mert a kiírásának elfelejtése bugokhoz vezetne.

Ennek érdekében egy új objektum létrehozásához inkább egy gyárat kell implementálni, és annak a belsejében létrehozni az új objektumot.

function Foo() {
    var obj = {};
    obj.value = 'blub';

    var private = 2;
    obj.someMethod = function(value) {
        this.value = value;
    }

    obj.getPrivate = function() {
        return private;
    }
    return obj;
}

A fenti kód ugyan ellenálló a hiányzó new kulcsszó hibáját illetően és megfelelően használ privát változókat, érdemes megemlíteni a dolgok kontra részét is.

  1. Több memóriát használ, mivel az így létrehozott objektumok nem osztják meg a prototípusukat egymás között.
  2. A származtatás macerás, mivel a gyár kénytelen ilyenkor lemásolni az összes származtatandó metódust egy másik objektumról, vagy ezt az objektumot be kell állítsa a létrehozott új objektum prototípusának.
  3. Az a megközelítés miszerint egy kifelejtett new kulcsszó miatt eldobjuk az objektum teljes prototípusát, ellenkezik a nyelv szellemiségével.

Összefoglaló

A new varázsszó kihagyása ugyan bugokhoz vezethet, de ez nem megfelelő indok arra hogy ezért eldobjuk a prototípusok használatát. Végeredményben mindig az fog dönteni a különböző stílusok megválasztása között, hogy mire van szüksége éppen az aktuális programunknak. Egy dolog azért elengedhetetlenül fontos, ez pedig hogy megválasszuk melyik stílust fogjuk használni objektumok létrehozásra, és ezt konzisztensen használjuk a teljes megoldáson keresztül.