Grunderna för objektorienterad JavaScript

Under de senaste åren har JavaScript alltmer blivit populärt, delvis på grund av bibliotek som är utvecklade för att göra JavaScript-appar / effekter lättare att skapa för dem som kanske inte har förstått kärnspråket helt.

Under det förflutna var det ett vanligt argument att JavaScript var ett grundsprog och var väldigt "slap dash" utan någon verklig grund; det här är inte längre fallet, särskilt med införandet av högskaliga webbapplikationer och "anpassningar" som JSON (JavaScript Object Notation).

JavaScript kan ha allt som ett objektorienterat språk har att erbjuda, om än med lite extra ansträngning utanför ramen för denna artikel.

Låt oss skapa ett objekt

 funktion myObject () ;

Grattis, du skapade bara ett objekt. Det finns två sätt att skapa ett JavaScript-objekt: de är "Constructor functions" och "Literal notation". Den ovanstående är en Constructor-funktion, jag ska förklara vad skillnaden är inom kort, men innan jag gör, här är vad en Objektdefinition ser ut som att använda bokstavlig notering.

 var myObject = ;

Literal är ett föredraget alternativ för namnavstånd så att JavaScript-koden inte stör (eller vice versa) med andra skript som körs på sidan och även om du använder det här objektet som ett enda objekt och inte kräver mer än en förekomst av objekt medan Konstruktorfunktionstypnotation föredras om du behöver göra några inledande arbeten innan objektet skapas eller kräver flera instanser av objektet där varje instans kan ändras under manusens livstid. Låt oss fortsätta bygga på båda våra objekt samtidigt så att vi kan observera vad skillnaderna är.

Definiera metoder och egenskaper

Konstruktorversion:

 funktion myObject () this.iAm = 'ett objekt'; this.whatAmI = function () alert ('jag är' + this.iAm); ; ;

Bokstavlig version:

 var myObject = iAm: 'ett objekt', whatAmI: function () alert ('I'm' + this.iAm); 

För var och en av objekten har vi skapat en egenskap "iAm" som innehåller ett strängvärde som används i vår objektmetod "WhatAmI" som varnar ett meddelande.

Egenskaper är variabler skapade inuti ett objekt och metoder är funktioner skapade inuti ett objekt.

Nu är det förmodligen lika bra som att förklara hur man använder egenskaper och metoder (även om du redan skulle ha gjort det om du är bekant med ett bibliotek).

För att använda en egenskap först skriver du vilket objekt det tillhör - så i det här fallet är det myObject - och sedan hänvisar till dess interna egenskaper sätter du ett stopp och sedan namnet på fastigheten så att det så småningom kommer att se ut som myObject.iAm ( detta kommer att returnera "ett objekt").

För metoder är det samma förutom att utföra metoden, som med vilken funktion som helst måste du lägga parentes efter det; annars kommer du bara att returnera en referens till funktionen och inte vad funktionen faktiskt returnerar. Så det kommer att se ut som myObject.whatAmI () (detta kommer att varna "Jag är ett objekt").

Nu för skillnaderna:

  • Konstruktörobjektet har dess egenskaper och metoder definierade med sökordet "detta" framför den, medan den bokstavliga versionen inte gör det.
  • I konstruktörobjektet har egenskaperna / metoderna sina "värden" definierade efter ett likartat tecken "=" medan de i bokstavsversionen definieras efter ett kolon ":".
  • Konstruktörsfunktionen kan ha (valfritt) halvkolonner ";" i slutet av varje fastighets- / metoddeklaration medan i bokstavsversionen om du har mer än en egenskap eller metod måste de vara separerade med ett kommatecken ',' och de kan inte ha halvkolon efter dem, annars kommer JavaScript att returnera en fel.

Det finns också en skillnad mellan hur dessa två typer av objektdeklarationer används.

För att använda ett bokstavligt noterat objekt, använder du det helt enkelt genom att referera till dess variabla namn, så vart det är nödvändigt kallar du det genom att skriva;

 myObject.whatAmI ();

Med konstruktörsfunktioner måste du inställa (skapa en ny instans av) objektet först; du gör det genom att skriva

 var myNewObject = nytt myObject (); myNewObject.whatAmI ();

Använda en konstruktörsfunktion.

Låt oss använda vår tidigare konstruktörsfunktion och bygga på den så att den utför vissa grundläggande (men dynamiska) operationer när vi instanserar den.

 funktion myObject () this.iAm = 'ett objekt'; this.whatAmI = function () alert ('jag är' + this.iAm); ; ;

Precis som vilken JavaScript-funktion som helst, kan vi använda argument med vår konstruktörsfunktion.

funktion myObject (vad) this.iAm = what; this.whatAmI = funktion (språk) alert ('I'' + this.iAm +' av '+ language +' språk '); ; ;

Låt oss nu instansera vårt objekt och ringa sin whatAmI-metod, fylla i de obligatoriska fälten som vi gör det.

 var myNewObject = nytt myObject ('ett objekt'); myNewObject.whatAmI ( 'JavaScript');

Detta kommer att varna "Jag är ett föremål för JavaScript-språket."

Att instantiera eller inte att instantiate

Jag nämnde tidigare om skillnaderna mellan Objektkonstruktioner och Objekt Literals och att när en ändring görs till ett Objekt Literal påverkar det objektet över hela skriptet, medan när en Constructor-funktion är instanserad och då ändras till den instansen, kommer inte att påverka några andra instanser av det objektet. Låt oss försöka ett exempel;

Först kommer vi att skapa ett objekt bokstavligt;

 var myObjectLiteral = myProperty: 'detta är en egenskap' // alert current myProperty alert (myObjectLiteral.myProperty); // detta kommer att varna "det här är en egendom" // ändra myProperty myObjectLiteral.myProperty = 'det här är en ny egendom'; // alert current myProperty alert (myObjectLiteral.myProperty); // det här kommer att varna "det här är en ny egendom", som förväntat

Även om du skapar en ny variabel och pekar den mot objektet, kommer det att ha samma effekt.

 var myObjectLiteral = myProperty: 'detta är en egenskap' // alert current myProperty alert (myObjectLiteral.myProperty); // detta kommer att varna "det här är en egenskap" // definiera ny variabel med objekt som värde var sameObject = myObjectLiteral; // ändra myProperty myObjectLiteral.myProperty = 'det här är en ny egendom'; // alert current myProperty alert (sameObject.myProperty); // det här kommer fortfarande att varna "det här är en ny egendom"

Låt oss nu försöka en liknande övning med en Constructor-funktion.

 // detta är ett annat sätt att skapa en Constructor-funktion var myObjectConstructor = function () this.myProperty = 'detta är en egenskap' // instansera vår Constructor var constructorOne = ny myObjectConstructor (); // inställa en andra instans av vår Constructor var constructorTwo = ny myObjectConstructor (); // alert current myProperty of constructorEn instansvarning (constructorOne.myProperty); // detta kommer att varna "det här är en egenskap" // varning nuvarande myProperty of constructorTwo exempelvarning (constructorTwo.myProperty); // det här kommer att varna "det här är en egendom"

Så som förväntat, returnerar båda rätt värde, men låt oss ändra myProperty för en av fallen.

 // detta är ett annat sätt att skapa en Constructor-funktion var myObjectConstructor = function () this.myProperty = 'detta är en egenskap' // instansera vår Constructor var constructorOne = ny myObjectConstructor (); // ändra myProperty of the first instance constructorOne.myProperty = 'det här är en ny egenskap'; // inställa en andra instans av vår Constructor var constructorTwo = ny myObjectConstructor (); // alert current myProperty of constructorEn instansvarning (constructorOne.myProperty); // detta kommer att varna "det här är en ny egenskap" // varning nuvarande myProperty of constructorTwo exempelvarning (constructorTwo.myProperty); // det här kommer fortfarande att varna "det här är en egendom"

Som du kan se från det här exemplet, trots att vi ändrade egenskapen till constructorOne, påverkade den inte myObjectConstructor och påverkar därför inte constructorTwo. Även om constructorTwo var instansierad innan vi ändrade egenskapen myProperty hos constructorOne, skulle den fortfarande inte påverka egenskapen myProperty för constructorTwo eftersom det är en helt annan förekomst av objektet i JavaScript-minne.

Så vilken ska du använda? Jo det beror på situationen, om du bara behöver ett objekt av sitt slag för ditt manus (som du kommer att se i vårt exempel i slutet av den här artikeln), använd sedan ett objekt bokstavligt, men om du behöver flera instanser av ett objekt , där varje instans är oberoende av varandra och kan ha olika egenskaper eller metoder beroende på hur det är konstruerat, använd sedan en konstruktörsfunktion.

Det här och det där

Medan man förklarade konstruktörfunktioner, fanns det många "här" nyckelord som kastades runt och jag räknar med vilken bättre tid att prata om räckvidd!

Nu kanske du frågar "vad är det här räckvidd du pratar om"? " Omfattning i JavaScript är funktion / objektbaserad, så det betyder att om du är utanför en funktion, kan du inte använda en variabel som definieras inuti en funktion (om du inte använder en stängning).

Det finns emellertid en räckviddskedja, vilket innebär att en funktion i en annan funktion kan komma åt en variabel definierad i dess moderfunktion. Låt oss ta en titt på några exempelkod.

Som du kan se i det här exemplet, var1 definieras i det globala objektet och är tillgängligt för alla funktioner och objekt, var2 definieras i funktion1 och är tillgänglig för funktion1 och funktion2, men om du försöker referera den från det globala objektet kommer det att ge dig felet "var2 är odefinierad", var3 är endast tillgänglig för funktion2.

Så vad gör "denna" referens? Tja i en webbläsare refererar "detta" till fönsterobjektet, så tekniskt är fönstret vårt globala objekt. Om vi ​​är inuti ett objekt kommer "detta" att referera till själva objektet, men om du är inne i en funktion, kommer det fortfarande att referera till fönstret objektet och likaså om du är inne i en metod som ligger inom ett objekt, det här kommer att referera till objektet.

På grund av vår omfattningskedja, om vi är inuti ett delobjekt (ett objekt i ett objekt), kommer "detta" att referera till delobjektet och inte moderobjektet.

Som sidnot är det också värt att lägga till att när du använder funktioner som setInterval, setTimeout och eval, när du utför en funktion eller metod via en av dessa, hänvisar "detta" till fönsterobjektet eftersom dessa är metoder för fönster, så setInterval ) och window.setInterval () är desamma.

Oj nu när vi har det ur vägen, låt oss göra ett verkligt världsexempel och skapa ett formvalideringsobjekt!

Real World Användning: Ett Form Valideringsobjekt

Först måste jag introducera dig till addEvent-funktionen som vi ska skapa och är en kombination av ECMAScripts (Firefox, Safari, etc ...) addEventListener () -funktionen och Microsoft ActiveX Script's attachEvent () -funktion.

 funktion addEvent (till, typ, fn) if (document.addEventListener) to.addEventListener (typ, fn, false);  annars om (document.attachEvent) to.attachEvent ('on' + typ, fn);  annat till ['på' + typ] = fn; ;

Detta skapar en ny funktion med tre argument, till att vara DOM-objektet som vi bifogar händelsen till, typ vara typ av händelse och fn är funktionsdriven när händelsen utlöses. Det kontrollerar först om addEventListener stöds, om så kommer det att använda det, om inte det kommer att kontrollera efter attachEvent och om allt annat misslyckas använder du förmodligen IE5 eller något lika föråldrat, så vi lägger till händelsen direkt på sin händelseegenskap (notera: det tredje alternativet kommer att skriva över någon befintlig funktion som kan ha lagts till händelseegenskapen medan de två första kommer att lägga till den som en extra funktion till dess händelseegenskap).

Låt oss nu skapa vårt dokument så att det liknar vad du kanske ser när du utvecklar jQuery-saker.

I jQuery skulle du ha;

 $ (dokument) .ready (funktion () // all vår kod som körs efter att sidan är klar går här);

Med vår addEvent-funktion har vi;

 addEvent (fönster, "ladda", funktion () // all vår kod som körs efter att sidan är klar går här);

Nu för vårt Form-objekt.

varformat = validClass: "valid", fname: minLängd: 1, maxLängd: 15, fältnamn: Förnamn, lname: minLängd: 1, maxLängd: 25, Fältnamn: 'Efternamn', ValiderLängd: funktion (formEl, typ) if (formEl.value.length> type.maxLength || formEl.value.length < type.minLength ) formEl.className = formEl.className.replace("+Form.validClass,"); return false;  else  if(formEl.className.indexOf("+Form.validClass) == -1) formEl.className +="+Form.validClass; return true;  , validateEmail : function(formEl) var regEx = /^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]2,9)$/; var emailTest = regEx.test(formEl.value); if (emailTest)  if(formEl.className.indexOf("+Form.validClass) == -1) formEl.className +="+Form.validClass; return true;  else  formEl.className = formEl.className.replace("+Form.validClass,"); return false;  , getSubmit : function(formID) var inputs = document.getElementById(formID).getElementsByTagName('input'); for(var i = 0; i < inputs.length; i++) if(inputs[i].type == 'submit') return inputs[i];   return false;  ;

Så detta är ganska grundläggande men kan enkelt utökas på.

För att bryta ner det här först skapar vi en ny egenskap som bara är strängnamnet på vår "giltiga" css-klass som lägger till giltiga effekter som en grön gräns när de tillämpas på formulärfältet. Vi definierar också våra två delobjekt, fname och lname, så vi kan definiera egna egenskaper som kan användas av metoder på annat håll, dessa egenskaper är MINLENGTH vilket är minsta antal tecken som dessa fält kan ha, Maxlängd Vilka är de maximala tecknen som fältet kan ha och fält namn som faktiskt inte används, men kan gripas till saker som att identifiera fältet med en användarvänlig sträng i ett felmeddelande (t.ex. "Förnamn fält krävs".).

Därefter skapar vi en validateLength-metod som accepterar två argument: Formel DOM-elementet som ska valideras och typ som hänvisar till ett av delobjektet att använda (dvs fname eller lname). Denna funktion kontrollerar om längden på fältet ligger mellan minlängd och maxlängdsintervall, om det inte är så tar vi bort vår giltiga klass (om den finns) från elementet och returnerar falskt, annars lägger vi till den giltiga klassen och returnerar Sann.

Då har vi en validateEmail-metod som accepterar ett DOM-element som en argumentation, då testar vi detta DOM-elementvärde mot ett regelbundet uttryck för e-posttyp. igen om det passerar lägger vi till vår klass och returnerar sant och vice versa.

Slutligen har vi en getSubmit-metod. Denna metod ges formens id och sedan loopar genom alla inmatningselement inom den angivna formen för att hitta vilken som har en typ av inlämning (typ = "submit"). Anledningen till den här metoden är att returnera Skicka-knappen så att vi kan inaktivera den tills formuläret är klart att skicka in.

Låt oss sätta detta valideringsobjekt att fungera på en riktig form. Först behöver vi vår HTML.

  



Låt oss nu komma åt dessa ingående objekt med hjälp av JavaScript och validera dem när formuläret skickas.

addEvent (window, load), funktion () var ourForm = document.getElementById ('ourForm'); var submit_button = Form.getSubmit ('ourForm'); submit_button.disabled = 'disabled'; funktionskontrollForm () var input = (Form.validateLength) (if (inmatningar [2])) submit_button.disabled = false; return true; submit_button.disabled = 'inaktiverat'; returnera false;; checkForm (); addEvent (ourForm, 'keyup', checkForm); addEvent ourForm, 'submit', checkForm););

Låt oss bryta ner den här koden.

Vi paketerar vår kod i addEvent-funktionen, så när fönstret är laddat körs det här skriptet. För det första tar vi vårt formulär med sitt ID och lägger det i en variabel som heter ourForm, då tar vi in ​​vår inlämningsknapp (med hjälp av vår formulärobjekt getSubmit-metod) och lägger den i en variabel som heter skickaknapp, och sätt sedan in de inloggade knappar inaktiverade attributet till "inaktiverat".

Nästa definierar vi en checkForm-funktion. Det lagrar alla inmatningar i formfältet som en array och vi bifogar den till en variabel som heter ... du gissade den ... ingångar! Därefter definierar det några nestade om uttalanden som testar vart och ett av fälten i ingångssystemet mot våra Form-metoder. Det här är anledningen till att vi återvände sant eller falskt i våra metoder, så om det returneras sant, skickar vi det om uttalande och fortsätter till nästa, men om det returneras falskt, lämnar vi if statements.

Efter vår funktionsdefinition utför vi funktionen checkForm när sidan initialt laddas och också bifogar funktionen till en nyckeluppgift och en inlämnings händelse.

Du kanske frågar, varför bifoga att skicka in om vi inaktiverade knappen Skicka. Tja, om du är inriktad på ett inmatningsfält och tryck på enter-tangenten, försöker det att skicka in formuläret och vi måste testa för detta, varför anledningen till att vår checkForm-funktion returnerar sant (skickar formuläret) eller falskt (skickar inte in form).

Slutsats

Så vi lärde oss hur man definierar de olika objekttyperna inom JavaScript och skapar egenskaper och metoder inom dem. Vi lärde oss också en smidig addEvent-funktion och fick använda vårt objekt i ett grundläggande verkligt exempel.

Detta avslutar grunderna för JavaScript Object Orientation. Förhoppningsvis kan detta börja dig på väg att bygga ditt eget JavaScript-bibliotek! Om du gillade den här artikeln och är intresserad av andra JavaScript-relaterade ämnen, lägger du in dem i kommentarerna eftersom jag gärna fortsätter skriva dem. Tack för att du läser.

Varför inte också kolla in utbudet av JavaScript-objekt på CodeCanyon. Du kan hitta skript för att skapa reglage, nedräkningar, laddare och uppladdare, och mycket mer.

Populära JavaScript-objekt på Envato Market