Diskuze: Vytváření objektů
V předchozím kvízu, Online test znalostí JavaScript, jsme si ověřili nabyté zkušenosti z kurzu.
Jurajs:3.9.2015 10:11
Nemá být ten začátek takhle? Jen se ptam
var planet = function(name, home){
this.name = "pluto";
this.home = "milky way";
};
Cauko,
v prvom pripade vytvoris prazdny objekt clanek. Potom mu pridas nove property: clanek.titulek a priradis do nich hodnotu - v tomto pripade to je string "OOP v JS". To iste mozes urobit aj pomocou takzvaneho objektoveho literalu.
Objektovy literal:
var clanek = {titulek: "OOP v JS",
text: "JavaScript a OOP",
publikovan: false,
publikovat: function() {this.publikovan = true;}
};
V druhom pripade do premennej planet je dosadena takzvana self-invoking funcion, cize funkcia ktora sa okamzite sama vykona. V tele funkcie su zadefinovane dve premenne name a home, pricom v returne sa vracaju v tvare {name: name, home: home}, co v zavere spravi planet.name = "pluto" a planet.home = "milky way" a ked na zaver si pozries co sa nachadza v premennej planet, tak vystup bude nasledovny:
Object {name: "pluto", home: "milky way"}
Ako som vyssie spomenul, aj v tomto pripade by mohol byt pouzity objektovy literal:
var planet = {name: "pluto",
home: "milky way"}
P.S.: @Jurajs: tvoja pripomienka sa mi paci, taktiez mi tam to this. intuitivne patri, avsak JS to nezozerie.
Neaktivní uživatel:14.9.2015 13:02
Ne nemá, to co provádí on je spuštění funkce jako anonymní ... to co provádíš ty je uložení funkce do proměnné ,takže zatímco on už vytvořil objekt pomocí konstruktoru, ty jsi jen vytvořil proměnnou, pomocí které by se ten objekt mohl vytvořit.
Jurajs:14.9.2015 13:08
No ale on měl ten začátek špatně, pokud umíš OOP v Javascriptu.
Správně je to takhle:
var planet = function(name, home){
this.name = "pluto";
this.home = "milky way";
};
On tam psal tohle:
var planet = (function() {
name = "pluto";
home = "milky way";
Peas:16.9.2015 11:27
Ano, mal tam napisane:
var planet = (function() {
name = "pluto";
home = "milky way";
...
Avsak name="pluto" a home = "milky way" v tomto kontexte vytvorilo dve globalne premenne name a pluto, ktore boli naplnene stringmi a v returne sa potom vykona vytvorenie novej property objektu s nazvom name a dosadi sa do nej hodnota naplnena v premennej name vyssie definovanej. Urcite to nie je najlepsi postup, kedze globalne premenne v JSku patria medzi worst parts a dalo by sa to vyriesit aj lepsie.
Neaktivní uživatel:17.9.2015 15:03
Ahoj,
nevím přesně co se snažíš říct, Peas tvojí připomínku na globálku
vidím, předtím jsem si nevšiml
takže mě zajímá názor vás obou na tuhle variaci jeho kódu:
var person = (function() {
var num = 23;
var str = "John";
//TODO some logic here
return {
name : str,
age : num
}
})();
console.log("Tohle je člověk: "+person.name);
Trochu mám z vás dvou pocit, že mluvíte oba o něčem jiném, já se
spíš přikláním k Peasovi, ten totiž neříká, že to či ono je špatně
nebo dobře - prostě globál ne - souhlas, nedává tam smysl...ale to co se
tam snažíš nacpat ty, mi přijde hrozně zjednodušený, přece nemusíš
vytvářet objekt v js jen takhle no ne?
Peas
Majkel:17.9.2015 15:17
Ahoj, abych vysvětlil svůj původní dotaz. Potom, co jsem si tady prošel všechny tutoriály na JS a jQuery, tak jsem si našel něco o návrhových vzorech v JS, které mě totálně zmátly
Neaktivní uživatel:17.9.2015 15:28
Ahoj,
přiznám se, že na tebe jsem už vlastně ani nereagoval, to spíš na Peas a
Jurajs, ale když jsi tady, předpokládám, že si čteš všechny komenty...
já k tomu tvému druhému postupu mám jen to, že když bys udělal něco
jako
var person = {
name : "Johnny",
age: 23,
skin : "white",
sex: "male"
};
tak by to asi nikomu tak divné nepřišlo... ale ty ses ptal na rozdíl mezi dvěma postupy, to je hrozně zapeklitá otázka, nikdo tu totiž netuší kolik další způsobů vytváření obejktů znáš...
PS: jeslti ten nahoře znáš a jen opakuju to co už víš, předem se pro jistotu omlouvám. Já jen, že mají s tím tvým druhým něco společného...
Neaktivní uživatel:17.9.2015 16:08
Mě to stejně nedá a musím to říct...
Objekty v JS:
pomocí konstruktoru, neanonymně:
function person(name, age, sex, ) {
this.name = name;
this.age = age;
this.sex = sex;
this.sayHelloTo = function(name) {
alert("Hello "+name);
}
}
person("John", 23, "male");
Význam: zapouzdření, možnost použít na neomezeně mnoho osob, takže je to doslova něco jako třída, funkce v proměnných normálně zavoláš
pomocí konstruktoru anonymně:
var person = function() {
this.name = "John";
this.age = 23;
this.sex = "male";
this.sayHelloTo = function(name) {
alert("Hello "+name);
}
}
Význam: zapouzdření, tady už ale nejde použít na víc osob, funkce se chovají stejně jako nahoře
jako JSON:
var person = {
name : "John",
age : 23,
sex : "male",
say: function (param) {
console.log("hello: "+param);
}
}
Význam: rychlé, dobře se v tom orientuje, zapouzdření, pracuješ s tím jako s JSONem
něco jako spojení JSONu a konstruktoru a anonymní samospouštěcí funkce :
function getDataFromDatabase(id) {
//TODO some database, some AJAX, something
return 23;
}
var person = (function() {
var num;
var str = "John";
//TODO some logic here
num = getDataFromDatabase(123);
return {
name : str,
age : num
};
})();
Význam: zapouzdření, vlastně je to dost podobný anonymnímu literalu (tomu druhému postupu), taky to tam rveš víceméně na tvrdo, samozřejmě můžeš udělat to co demonstruju a ty proměnný naplnit podle nějaký logiky, nicméně výhodou může být to, že v tom returnu si nakomponuješ zase JSON objekt, teda zase přehlednost a dobrá orientace
ještě jde použít něco jako pole a nedivil bych se kdybych na něco zapomněl, ALE co sem tím chtěl říct, že každej z těch postupů má svojí velmi silnou stránku, pokud se provede správně, rozhodně bych neřekl, že jen jako object literal je správně ... a doufám, že jestli Majklovi něco do teď nebylo jasný, nebo byl zmatený tak po tomhle už je všechno clear
PS: Pokud nemám pravdu, nebo kdokliv neshouhlasí, pokud jsem něco pochopil špatně, nebo špatně popsal, prosím, jsem přístupný opravě, přece jenom jsem člověk a chybovat je moje právo.
Neaktivní uživatel:17.9.2015 16:31
Edit: v prvním postupu jsem na poslední řádku udělal chybu:
má to vypadat takhle:
var clovek = new person("Johnny", 23, "male");
jak jsem říkal, chybička se vloudí
Jurajs:17.9.2015 18:40
Ahoj, jen jedine reknu a to v dobrém nechci, aby to tady někdo bral zle atp...A ted k tomu kodu, ja jsem na zacatku teto diskuze jen upozornoval na chyby kde měl psane:
var planet = (function()
Ta zavorka pred function bý nema...pokud vím. A jeste jedna vec...kde ma parametry? Tam byt nemusi? Kdyz ma hned na druhem radku name a home, prece za function v zavorce by meli byt ty parametry - name a home?
Neaktivní uživatel:17.9.2015 22:30
Ta závorka tam být může, jde pak o něco jiného než to cos ukazoval ty... stále ale jde o objekt, navíc parametry nejsou nic povinného..pokud je do konstruktoru nechce, tak je tam přivolávat nemusí... faktem je, že on totiž nejen, že má závorku hned na začátku, ale celý ten konstruktor má pěkně obalený i tou druhou kulatou závorkou a taky má hned za nima další dvě - značící volání funkce... zkrátka jde o to že do proměnné planet uložil self invoking funkci (zkrátka sebe volající konstruktor), který vrací objekt .... já jako javascripťák a javista se nad tímhle postupem docela bavím, protože když by se to ještě trochu upravilo, nejen že je to správně, ale navíc dostaneš z hlediska OOP a z pohledu JAVA programátora (byť začínajícího) skutečný konstruktor jak má být - považ..zavoláš ho ... sice bez new, ale to nevadí, a on VRÁTÍ objekt..no není to na první pohled nádhera? a pak že javascript nenabízí kvalitní objekty... blázni kdo na něj nadávaj... nad tímhle kdyby někdo udělal nějakej robustní framework pro nooby a dal to veřejnosti jako "vylepšenej" javascitp tak ti většina lidí řekne : No ! Konečně jste JS dali pořádný objekty!"... a vůbec by nevadilo, že to tam je už jak dlouho... no abych jen nebásnil... je to asi o tomhle:
function giveMeFirstName(gender) {
return gender == "male" ? "John" : "Suzan";
}
function giveMeLastName() {
return "Wick";
}
var person = (function() {
var firstName = "";
var lastName = "";
var age = 0;
var gender = "male";
var skinColor = "white";
var cry = function() {
alert("Úuuuuuuu");
};
firstName = giveMeFirstName(gender);
lastName = giveMeLastName();
return {
firstName : firstName,
lastName : lastName,
age : age,
cry : cry,
saySmthing : function(sayWhat) {
console.log(sayWhat);
},
gender : gender,
color : skinColor
};
})();
person.saySmthing("hello ppl");
person.cry();
console.log(person.color);
mimochodem tady je Live DEMO: http://jsfiddle.net/…ll/jLh0ke70/
a kdybych to měl nějak popsat... v podstatě je to funkční řešení, který může mít za určitých okolností naprosto jasný smysl... je to celé inspirované tímhle
var planet = {
name : "Pluto",
stillPlanet : false,
sayGoodBye : function() {
console.log("Bye bye");
},
magicNumber : 23
}
stejně jako nahoře... tady pevně dáváš všechny property do objektu... což je super, ale co když to chceš udělat nějak s logikou? No použiješ to zapouzdření pomocí (function()....... výhodou je, že když ten objekt stavíš, máš jistotu, že ti chyba v kontextu nenaboří ten objekt a navíc můžeš při tvorbě toho objektu nevědět jeho property (teda spíš obsah) .. to je přece neskutečnej luxus pro programátora ne?
A jelikož jsem se do toho fakt hodně položil, zajímalo mě jestli by to teda šlo obalit tak, aby to vypadalo jako v JAVĚ ... mám tu pro zajímavost dvě dema ... první z nich je trochu šílenej na parametry, ale v podstatě je to správně, jen to hrozně vypadá, ten druhej už parametry ohendluje úhledně a zbavuje se i použití slovíčka new ... takže v podstatě je to Class -> v ní je kostruktor (doslova konstruktor, protože vytváří a vrací instanci) -> dál jsou stále v Class zapouzdřeny další funkce a vlastnosti objektu ... já chápu, že se to většině asi nebude líbit a vůbec bych se nezlobil, kdyby mi nějaký profi JS programátor řekl, že tam aplikuju smrtící věci, ale já profík zatím nejsem, tak mi nezbývá než to pustit sem a čekat jestli se někdo najde.
http://jsfiddle.net/…ll/7saLuc8k/ v1
http://jsfiddle.net/…ll/nby5xj2f/ v2
Zobrazeno 15 zpráv z 15.