Avatar billede Slettet bruger
18. marts 2011 - 15:20 Der er 10 kommentarer og
1 løsning

jQuery - sær konstruktion ?

Man ser tit kodestumper, som bare skal køre en enkelt gang, pakket ind på denne måde:

$(function(){

    var a = "123";
    alert ("a = "+a);

});

Men hvorfor - det virker umiddelbart overflødigt..
Avatar billede intenz Novice
18. marts 2011 - 15:36 #1
Det er jquerys 'shorttag' for window.onload eventen.

Skrives det sådan:
var a = "123";
alert ("a = "+a);

vil koden blive kørt så snart browseren når til linjen (uanset hvad der kommer efter).

Skrives det sådan:
$(function(){
    var a = "123";
    alert ("a = "+a);
});

Vil koden først blive kørt efter hele siden er hentet/parsed. Man sikrer herved at hele siden er indlæst inden man begynder at køre sit javascript.

Den samme kode i 'native' javascript ser sådan ud:

// uden onload
alert(123);

// med onload
window.onload = function() {
  alert(123);
}
Avatar billede olebole Juniormester
18. marts 2011 - 18:48 #2
<ole>

$ er navnet på jQuery's centrale funktion, som gør forskelligt - alt efter konteksten. I spørgsmålet kalder du funktionen med et argument - og argumentet er en funktion.


// Dette kald ligner noget, du kender:
    dollarTegn(argument);

// Et argument kan være alle former for JS-objekter
// -- f.eks: strenge, tal, arrays - og funktioner:
    dollarTegn(function(){/* do something */});

// Hvilket fører videre til:
    $(function(){/* do something */});



Det er noget frygtelig snavs, at funktionen ikke er entydig - men at man har valgt $ som navn til funktionen er et totalt mysterium. $ er i følge ECMA standarden fortrinsvis forbeholdt maskinkode og bør aldrig bruges som identifier

/mvh
</bole>
Avatar billede olebole Juniormester
18. marts 2011 - 18:53 #3
- og et helt simpelt eksempel på, hvad man kan med en funktion, der medsendes som argument til en anden funktion:


function fooBar(fn) {
    fn("Et argument, der skal alert'es.");
}

fooBar(function(sStr){alert(sStr)});

Avatar billede olebole Juniormester
18. marts 2011 - 18:59 #4
- men man skal være yderst forsigtig med den slags konstruktioner! JavaScripts closures er ekstremt kraftfulde, men bruges de uden indsigt, bliver det meget let noget skidt - og i værste fald går det helt galt.

I modsætning til den almindelige opfattelse kræver det langt mere og dybere JavaScript/DOM indsigt at skrive god kode med jQuery, end det gør uden  *o)
Avatar billede Slettet bruger
19. marts 2011 - 12:30 #5
Hej igen, måtte lige væk fra skærmen :(

@intenz - Ja, det har du sgu ret i - Nedenstående alerter først "mystik" og så "ready":

$(function() { alert ("mystik") });
$(document).ready(function(){ alert("ready") });

Mens nedenstående, først "ready" og derefter "mystik"

$(document).ready(function(){ alert("ready") });
$(function() { alert ("mystik") });

Så det giver point'ene : )

@olebole - Helt enig. Det er sgu noget lumskeri : )

Jeg er ikke helt ny på javascript - har i hvertfald levet af det i mange år : )
- og har også tidligere benyttet functions som argumenter, f.eks. i timeout/interval:
setTimeout(function(){alert("Tiden er gået, MAU!")},5000)

Men jeg er faktisk allerede "omvendt" til jQuery (og dermed JSON) måden at "tænke på", for selvom det ikke "ligner" javascript og kan være svært at degugge. får man så meget "forærende" - ikke mindst med jQueryUI.

Helt enig i betragtningen, at jQuery IKKE er lettere at forstå end "ren javascript" - bortset fra ét område: Browser-quirks - herligt at slippe for at skulle bakse med forskellige måder at opnå det samme på (ok NÆSTEN slippe for det..)

Jeg arbejder på et større fælles-kalender-system, men er netop startet helt forfra - nu baseret på jQuery (og -UI), og min kode fylder kun en fjerdedel af før, på trods af at der er MANGE flere "finesser"!

CHOCK: I aftes prøvede jeg det lige på min søsters android - Det virkede sgu - helt uden at jeg har taget hensyn til det!
- ALT bortset fra mouseover-funktionalitet (som desværre er ret central, så det skal lige omtænkes..)


TAK til jer begge for indsigtsfulde bidrag (above-and-beyond) : )
Avatar billede olebole Juniormester
19. marts 2011 - 19:50 #6
Dit timeout eksempel er et ganske udmærket eksempel på en konstruktion, der kan være yderst problematisk, hvis man ikke er rigtig stiv i JavaScript's closures og hvordan de forskellige browseres garbage collection virker.

Jeg husker for et par år siden, at en af Ekspertens aller mest respekterede JavaScriptere havde skrevet en lille, lokal, HTML-baseret app, der kaldte E - og overvågede/udskrev de senest oprettede spørgsmål. Vel at mærke en app, der i modsætning til E's feeds kørte opdateringerne realtime.

Alt var fint - bortset fra, at den kun kunne køre et par timer, hvorefter browseren gik ned med et dybt suk. Selvom han, hvad viden og erfaring angår, hørte til i frontend kodens absolutte Top3 på Eksperten, havde han ikke haft fokus på dette område.

Efter en snak om closures og oddities omkring de forskellige browseres RAM-brug og garbage collection fik han lavet en app, der kunne holde til at arbejde i timevis/dagevis uden at tabe pusten.

Dengang, man skiftede sider hele tiden, betød det ikke helt så meget, men nu, hvor man opdaterer samme side hundredevis - og somme tider tusindvis - af gange, har det meget stor betydning  *o)

Det er rigtigt, du med jQuery får en masse 'gaver'. Det gør du også, hvis du får 50 levende kyllinger i julegave. Mindst et helt års forbrug af grillkyllinger, hotwings og nuggets ... WoW!
Men vent, til du har indset, hvad det kræver at passe 'gaven' og nå frem til at se dele af den på middagsbordet.

En kønssygdom kan jo også betragtes som en slags 'gave' - men jeg tillader mig lige at springe over  *D
Avatar billede Slettet bruger
20. marts 2011 - 13:48 #7
Hm.. Closures, gad vide... ?
Den lange: http://jibbering.com/faq/notes/closures/
Den korte: http://www.javascriptkit.com/javatutors/closures.shtml  <= anbefalet

Som ex-C-programmør, er jeg "naturligt" opmærksom på scope..
- men det er åbenbart mere kompliceret i javascript - "secret references" !

Du har ret: En begynder som går direkte til jQuery kunne let komme i varmt vand her!
Avatar billede olebole Juniormester
20. marts 2011 - 16:39 #8
Rigtig mange jQuery brugere - begyndere eller ej - står faktisk i spilkogende vand til halsen, men opdager det sjældent, da biblioteket oftest bruges til småprojekter. Ofte vil en velskrevet kode dog kun bruge 1-10% af de ressourcer, jQuery bruger til samme opgave - og koden behøver såmænd ikke at være væsentligt større. Til gengæld vil den være gennemskuelig.

Et væsentligt problem ved JavaScript/JScript (som, når man dykker lige ned under overfladen ikke er én og samme ting!) er den enormt flade indlæringskurve. Det gør, at de fleste i grove træk ophører med at søge uddybende viden om emnet, når de har set alert("Hello World") virke. Det bedste, man kan sige om langt flertallet af WWW's JavaScriptere, er: "Der synes at være huller i uvidenheden!"  *o)

JavaScript og JScript bygger som bekendt på ECMAScript, men netop måden, hvorpå garbage collection er implementeret, er ikke standardiseret af ECMA. Da de to implementeringer er væsentligt forskellige, vil mange ting performe helt forskelligt - afhængigt af, hvilken browser koden afvikles i.

Jeg testede over en længere periode et utal af forskellige scenarier i IE6 og blev rystet over resultaterne. F.eks. var der voldsom forskel på, hvornår man tilføjede en event handler til et DOMElement, der indsættes i DOM træet. Hvis handleren blev tilføjet før DOM-indsættelsen, skete der et væsentligt memory leak. Det skete ikke, når handleren blev tilføjet efter indsættelsen.

Det skyldtes, at der - når elementet fik tilføjet handleren, mens det lå i hukommelsen - blev oprettet et midlertidigt script scope i hukommelsen ... og at dette blev ikke frigivet, når elementet blev indsat  :o|

Endvidere var det som nævnt meget let at oprette cirkulære referencer til DOMElementer henover en closure - og den slags var næsten umulige at få opløst igen.

Jeg ændrede mine kodevaner væsentligt og har efterfølgende ikke forsket helt så meget i emnet. Ifølge sædvanligvis pålidelige kilder ved jeg dog, at der er sket en hel del forbedringer af specielt JScript's garbage collection og performance - men at der stadig er vældig god plads til yderligere forbedringer. At MS selv skulle til at bruge Ajax og mere ekstensive DOM manipulationer i deres indtægtsgivende produkter gjorde, at de var nødt til at gøre noget ved problemerne.

Man skal ikke glemme, at JavaScript/JScript oprindelig var beregnet til at tilføje lidt eye-candy til små, ukomplicerede, ikke-dynamiske websider, der hele tiden blev skiftet i browseren (hvorved en stor del af den 'leakede' hukommelse blev frigivet). Dagens dynamiske applikationer, hvor sidens DOM hele tiden manipuleres er en fuldstændig anden verden.

I øvrigt er det tankevækkende, at Firefox generelt har problemer med håndtering af lange strenge - og at IE's garbage collection heller ikke har det godt med dem. Hvis man sammenholder dette med, at det ofte kræver op til 5-10 gange så mange serverressourcer at formatere data som HTML fremfor som XML eller JSON, må det anses som half past uhensigtsmæssigt (læs: tåbeligt) at returnere HTML i forbindelse med XHR (XMLHttpRequests/Ajax) og indsætte i siden med innerHTML. Jeg har dog forlængst erfaret, at det at sige den slags højt, er langt værre end at massevoldtage små, lodne egernbørn!  =)
Avatar billede Slettet bruger
20. marts 2011 - 17:27 #9
Hm.. nu bliver jeg bekymret - og ikke bare for de små, lodne egernbørn : )

Er det muligt at konstatere memoryleaks - uden bananstik og hvid kittel ?
- og med det mener jeg direkte fra scriptet selv:
Efter det er "genneminitialiceret" - se hvormeget memory man har brugt.
Køre en suspekt funktion 100 gange - og så kigge på memoryforbrug igen.
Avatar billede olebole Juniormester
20. marts 2011 - 17:41 #10
*LoL* Don't worry! *Beep-beep-bzzz beep-beep* We come in peace and won't harm your planet! *D

Ja, den simple test er at lave store loops og se på, hvad din taskmanager siger om memory forbruget.

Du kan også lave en side, der på onload laver en operation f.eks. 10 gange - og derefter reloader sig selv. Hvis dette får memory forbruget til at stige over tid, har du fat i de seriøst problematiske leaks, som ikke engang løses ved sideskift.
Avatar billede Slettet bruger
21. marts 2011 - 08:55 #11
Ja selvfølgelig : )

- havde bare håbet du havde opskriften på en JS funktion der "lige" kunne løbe hele window/document-objectet igennem, og lægge det hele sammen : )
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester