Avatar billede askalot Mester
14. april 2012 - 00:08 Der er 55 kommentarer og
1 løsning

String.replace dynamisk?

Hej

str.replace(/microsoft/gi, "W3Schools");

- fint nok..

Men hvordan laver jeg det til en funktion?

var sReplace = function(str,a,b){
return str.replace(/\+a+\/gi, "W3Schools");
}

virker ikke..
Avatar billede alphabits Nybegynder
14. april 2012 - 01:11 #1
Du kan lave et RegExp-object:

var sReplace = function (str, a, b) {
    return str.replace(new RegExp(a, "gi"), b);
}
Avatar billede askalot Mester
14. april 2012 - 01:16 #2
ey tak!- smid gerne svar! =)
Avatar billede alphabits Nybegynder
14. april 2012 - 01:34 #3
svar :)
Avatar billede olebole Juniormester
14. april 2012 - 16:26 #4
<ole>

Der er flere muligheder, og du kan f.eks. skrive noget i stil med:

function sReplace(str, a, b) {
    return str.split(a).join(b);
}

- alt efter, hvad det skal bruges til - og hvordan.

Det er i øvrigt vigtigt at huske, at når man opretter en funktion med en function operator som i #1, er det meget vigtigt at afslutte udtrykket med et semikolon:

var sReplace = function (str, a, b) {
    return str.replace(new RegExp(a, "gi"), b);
};  // <-- dér

Ellers kan der opstå uventede ting  =)

/mvh
</bole>
Avatar billede askalot Mester
14. april 2012 - 17:25 #5
Hej ole

mange tak for kommentaren

Hvad mener du med function operator?..

Sådan her?
myvar = function(){}

Det har jeg dog aldrig haft problemer med før. Har generetlt ikke problemer med semi kolon, og tilføjer dem kun for at gøre det lettere for parseren ( hvis det giver menging)

Er det fordi der er regepx indblandet..eller er det bare generelt?
Avatar billede olebole Juniormester
14. april 2012 - 17:41 #6
Alle expressions skal være afsluttet af et semikolon i JS. Prøv f.eks. disse to koder:

var foo = function() {
    alert("Hep")
}
(function() {
    alert("Hop");
})();

foo();

- og:

var foo = function() {
    alert("Hep")
};  // <-- Bemærk semikolon!
(function() {
    alert("Hop");
})();

foo();

Pokker til forskel det lille semikolon gør - og der kan laves andre eksempler, hvor det går galt  ;o)

Derimod fungerer dette som forventet:

function foo() {
    alert("Hep")
}
(function() {
    alert("Hop");
})();

foo();

- fordi funktionen foo ikke oprettes i en expression (med en function operator), men med et function statement
Avatar billede askalot Mester
14. april 2012 - 18:12 #7
Ah ok ja.. nu plejer jeg heller aldrig at bruge den slags syntax.

Kan du forklare mig hvorfor du ikke bare skriver:
alert("Hop");

Er det for at kunne oprette et midlertidigt scope, uden at oprette en instans?
Avatar billede askalot Mester
14. april 2012 - 18:17 #8
Normalt plejer jeg bare at wrappe i en function, og så kalde den.. men jeg kan da godt se at hvis man wrapper i en function, slipper man for overhovedet at have en instance af function (ved ikke om "instance" er det rigtige term, jeg er selvlært :P)
Avatar billede olebole Juniormester
14. april 2012 - 18:17 #9
Det meste moderne JS er opbygget på denne måde. Der kan være flere årsager, men en af dem er at undgå, at det globale scope/namespace bliver 'forurenet' af et hav af variabler - altså at holde en del variabler i et lokalt scope bag en closeure.
Avatar billede askalot Mester
14. april 2012 - 18:17 #10
Mente wrapper en function i parenteser..
Avatar billede askalot Mester
14. april 2012 - 18:18 #11
ok, kan godt se det.
Avatar billede askalot Mester
14. april 2012 - 18:18 #12
så lærte jeg det, mange tak =)
Avatar billede olebole Juniormester
14. april 2012 - 18:24 #13
Du kan også bruge syntaksen til at afvikle en funktion i load-øjeblikket - og dermed definere en funktions virkemåde udfra en betingelse:

var setEvent = (function(){
    if (window.addEventListener) {
        return function(elm, stype, fn){
            elm.addEventListener(sType, fn, false)
        };
    } else {
        return function(elm, stype, fn){
            elm.attachEvent("on"+sType, fn);
        };
    }
})();

Så snart browseren/fortolkeren har læst denne kode, vil funktionen setEvent indeholde script, der efterfølgende er afpasset, hvad den aktuelle browser understøtter
Avatar billede olebole Juniormester
14. april 2012 - 18:25 #14
- og uden fejl med små og store bogstaver  *D

var setEvent = (function(){
    if (window.addEventListener) {
        return function(elm, sType, fn){
            elm.addEventListener(sType, fn, false)
        };
    } else {
        return function(elm, sType, fn){
            elm.attachEvent("on"+sType, fn);
        };
    }
})();
Avatar billede olebole Juniormester
14. april 2012 - 18:27 #15
- og fidusen er selvfølgelig, at funktionen ikke skal spørge på, hvad browseren understøtter, hvergang den bliver kaldt. Det er afgjort på onload  =)
Avatar billede olebole Juniormester
14. april 2012 - 18:35 #16
Til sidst et eksempel på, hvordan du i OOP kan bruge syntaksen til at beskytte variabler:

(function(){
    // 'Beskyttet' variabel
    var counter = 0;
   
    // Constructor funktion
    function MyObj() {
        this.id = "instans_" + (counter++);
        this.foo = "noget";
    }
   
    // Gør klassen tilgængelig i det globale scope
    window.MyObj = MyObj;
})();

var fooBar = new MyObj();
alert(fooBar.id);

var fooBaz = new MyObj();
alert(fooBaz.id);

Variablen counter kan bruges af constructor funktionen, men kan ikke nås/ændres fra det globale scope
Avatar billede askalot Mester
14. april 2012 - 18:41 #17
ahh ok.. skulle lige se at den også var wrapped i paranteser efter setEvent = ..det giver mening!

(jeg kommer fra flash  actionscript, så har aldrig set dette før, man kan ikke wrappe functioner i paranteser dér, har lige testet ^^)
Avatar billede olebole Juniormester
14. april 2012 - 18:46 #18
Du kan også bare nøjes med:

var foo = function() {
    alert("Hep");
}();

- eller sende et argument med:

var foo = function(str) {
    alert("Hep"+str);
}("Hey");

Closures er et enormt stærkt værktøj i JS - selvom visse browseres garbage collection (specielt IE's) i mange år havde svært ved at håndtere dem i meget dynamisk JS/DOM kode
Avatar billede olebole Juniormester
14. april 2012 - 18:55 #19
Her er en ganske spændende video om bl.a. closures. Foredragsholderen er Douglas Crockford, som bl.a. står bag JSON. Enjoy  *o)
Avatar billede askalot Mester
14. april 2012 - 18:57 #20
Hmm lige nu sidder jeg faktisk i JScript (via cscript på windows).. men det virker også dér  =)
Avatar billede askalot Mester
14. april 2012 - 18:57 #21
Hehe..tak for link =)
Avatar billede olebole Juniormester
14. april 2012 - 19:05 #22
Ja, JScript og JavaScript bygger på samme standard, ECMA. Det burde AS egentlig også, men Adobe løb for hurtigt og for langt forude, da der på et tidspunkt var tale om en ny version af ECMA. De fik implementeret en del, der aldrig blev til noget  :o|
Avatar billede askalot Mester
14. april 2012 - 19:06 #23
Klasse eksemplet er nice.. skal lige lure det..
Har ikke før set en ordentlig constructor i klasse..

Nu hvor jeg har dig.. kan du vise mig hvordan man laver en ordetlig getter setter. ( skal helst kunne fungere i jscript :o )
Avatar billede olebole Juniormester
14. april 2012 - 19:19 #24
I hvilken sammenhæng mener du? Skal det være i en klasse, eller?
Avatar billede askalot Mester
14. april 2012 - 19:37 #25
Ja som klasse.

sådan at man f.eks kan sige minKlasse.url

Indebag ved er den property egentlig en function som returnerer en værdi

Hvis man siger minKlasse.url = "http://google.com" sker der igen et functions kald inde i klassen, som så gør nogle ting.

og selvfølgelig også for at beskytte variabler og funktioner så de ikke bliver overskrevet af "brugeren" ved en fejl.
Avatar billede askalot Mester
14. april 2012 - 19:44 #26
Jeg så engange noget med

set value(){
return _value
}, get value(val){
_value = val
}

men 1. Kunne hvis ikke få det til at virke..
2. Meget mærkeligt underscore konvetion
3. Eksemplet jeg så det brugt i, var via en prototype.. hvilket jeg ser tit i javascript(klasser) .. men det prøver jeg at holde mig fra.. ved ik hvorfor, synes bare det er noget rod =)
Avatar billede askalot Mester
14. april 2012 - 19:46 #27
...selvom prototype ser ud til at være en måde man kan nedarve på... damn.. JS er lidt mere avanceret end AS :P , men kan godt lide at det er endnu mere "frit"
Avatar billede askalot Mester
14. april 2012 - 19:49 #28
Forsøgte mig tidligere her..
http://www.eksperten.dk/spm/960946

- men synes bare det blev alt for rodet..og mega meget ekstra kode.
Avatar billede olebole Juniormester
14. april 2012 - 20:38 #29
Det er meget almindeligt at prefix'e 'beskyttede' properties med en underscore:

function MyObj() {
    this._width = 50;
}
var p = MyObj.prototype;
p.getWidth = function() {
    return this._width;
};
p.setWidth = function(val) {
    this._width = val;
};

Så kan du ikke skrive INSTANS.width = 123;, men skal gennem getter/setter. Du kan selvfølgelig altid skrive INSTANS._width = 123; ... so much for protection!  =)

Du kan også skrive:

function MyObj() {
    this._width = 50;
}
var p = MyObj.prototype;
p.width = function(val) {
    if (typeof val=="number") this._width = val;
    else return this._width;
};

Så hedder både setter og getter INSTANS.width. Funktionaliteten afgøres af, om du sender et argument med eller ej.

Andre bruger en metode til at tilknytte properties med tilhørende getter og setter til en klasse:

function MyBaseObj() {
   
}
var p = MyBaseObj.prototype;
p.initProp = function(name, initVal) {
    if (!this.hasOwnProperty("_"+name)) {
        this["_"+name] = initVal;
    }
    var sUpperName = name.charAt(0).toUpperCase()+name.substr(1);
    this["get"+sUpperName] = function() {
        return this["_"+name];
    };
    this["set"+sUpperName] = function(val) {
        this["_"+name] = val;
    };
};

var obj = new MyBaseObj();
obj.initProp("width", 123);

alert(obj.getWidth());
obj.setWidth(567);
alert(obj.getWidth());

Her er meningen selvfølgelig, at metoden initProp nedarves til andre klasser, som extend'er MyBaseObj.
Avatar billede askalot Mester
14. april 2012 - 21:07 #30
Hmm ok, ikke helt hvad jeg ledte efter, det kna nok ikke lade sig gøre i JS. Det tætteste jeg kommer er:

--------------------------------------

function myClass(val){
    var _foo = val;
}

myClass.prototype = {
    get theFoo(){ return _foo; },
    set theFoo(val){ _foo = val;}
};

myInstance = new myClass(4);

//hente foo
fooIs = myInstance.theFoo;
document.write(myInstance.theFoo);

//Ændre foo
myInstance.theFoo = 38;
document.write(myInstance.theFoo);

-------------------------------

Det virker ikke fordi _foo ikke er i defineret med this._for
Og hvis jeg tilføjer this. så er variable jo tilgængelig til at ændre.. og hele ideen går lidt af det. =)

Nå men tak fordi du tog dig tid til at forklare.. jeg håber andre også newbs kan få gavn af dette.
Avatar billede askalot Mester
14. april 2012 - 21:08 #31
*Det virker ikke fordi _foo ikke er i defineret/ref med this._foo
Avatar billede olebole Juniormester
14. april 2012 - 21:16 #32
Nej, det virker ikke, fordi koden:

myClass.prototype = {
    get theFoo(){ return _foo; },
    set theFoo(val){ _foo = val;}
};

- ikke giver mening i JavaScript. Sådan skal koden se ud:

function myClass(val){
    this._foo = val;
}

myClass.prototype = {
    getFoo: function(){ return this._foo; },
    setFoo: function(val){ this._foo = val;}
};

- hvilket bare er en lidt anden måde at skrive første eksempel i #29
Avatar billede askalot Mester
14. april 2012 - 21:22 #33
hmm , den virker da hér :)
http://jsfiddle.net/squadjot/SE4yR/
Avatar billede askalot Mester
14. april 2012 - 21:28 #34
og.. nej vel ikke helt det samme som #29.. fordi der skulle du jo stadig kalde det med en function

Se den fiddle dér.. den illustrérer pæcis hvad jeg leder efter..bortset fra at _foo er tilgængelig..fordi den defineres med this.
Avatar billede olebole Juniormester
14. april 2012 - 21:38 #35
Den syntaks er meget ny, og du skal ikke regne med, at lidt ældre browsere accepterer den
Avatar billede askalot Mester
14. april 2012 - 21:51 #36
ok, tak =)
Avatar billede askalot Mester
14. april 2012 - 21:54 #37
Men super med closures, så kan man også bruge det til klasser man alligevel kun skal bruge een gang.

MySingleInstance = new (function(){
this.val = "hello";
})();
Avatar billede olebole Juniormester
14. april 2012 - 21:55 #38
Selvtak  =)

Syntaksen hører til under ECMA5. I JavaScript betyder det fra version 1.8.5 (fra Firefox 4). Jeg er ikke sikker på, hvornår IE begyndte at understøtte syntaksen, men IE6 gjorde i hvertfald ikke. Jeg har ikke i skrivende stund mulighed for at teste i IE7 eller 8  =)
Avatar billede olebole Juniormester
14. april 2012 - 21:56 #39
Nuvel, men så kan du ligeså godt bruge en object literal:

MySingleInstance = {
    val = "hello"
};
Avatar billede olebole Juniormester
14. april 2012 - 21:57 #40
Oooops  :D

MySingleInstance = {
    val: "hello"
};
Avatar billede askalot Mester
14. april 2012 - 21:58 #41
dét der er vist ikke en syntax der giver mening i javascript ;)
Avatar billede askalot Mester
14. april 2012 - 21:59 #42
hovsa.. ja..ok

men det er jo ik helt det samme ;)
Avatar billede olebole Juniormester
14. april 2012 - 21:59 #43
Uundværlig JavaScript reference  *o)
Avatar billede olebole Juniormester
14. april 2012 - 22:00 #44
#42: Joda. Hvad mener du forskellen skulle være?
Avatar billede askalot Mester
14. april 2012 - 22:00 #45
a'la

MySingleInstance = new (function(){
var myFunc = function(){
return 10
}

this.otherObj = "something"
this.val = "hello";
this.getStuff = function(){
return myFunc()+45
}
})();
Avatar billede askalot Mester
14. april 2012 - 22:01 #46
ja asso.. man får lov til at opretholde et seperat scope?
Avatar billede askalot Mester
14. april 2012 - 22:04 #47
Man laver ikke bare et objekt..man laver rent faktisk en klasse.
Avatar billede askalot Mester
14. april 2012 - 22:04 #48
eller.. man laver en instans af en generisk klasse.. i guess
Avatar billede askalot Mester
14. april 2012 - 22:05 #49
nej.. man laver en instans af en klasse.. bum
Avatar billede olebole Juniormester
14. april 2012 - 22:09 #50
Du instatierer bare et object. Du har ingen constructor (= ingen klasse)  *o)

Hvad den beskyttede funktion angår kan du gøre sådan:

(function(){
    function myFunc(){
        return 10
    }
   
    window.MySingleInstance = {
        otherObj: "something",
        val: "hello",
        getStuff: function(){
            return myFunc()+45
        }
    };
})();
Avatar billede askalot Mester
14. april 2012 - 22:18 #51
ok, hmm =), mange måder at gøre tingene på

- lige med det eksempel, jeg går udfra jeg bare skal droppe window. hvis jeg er i jscript/cscript miljø


Jeg kan godt se man opnår "næsten" det samme..

Jeg troede også at hvergang man sagde "new" så oprettede man en instans af en klasse.

function myClass(val){
    // indtil videre er dette bare en alm function.
    this._foo = val; // bortset fra at hvis det bare var en alm function, så ville this ikke give mening.

}

myClass.prototype = {
// og vel også grunden til at man overhovedet kan bruge prototype
};

myInstance = new myClass()// <--
Avatar billede askalot Mester
14. april 2012 - 22:24 #52
jo mere jeg kigger på dit eksemepel i #16, jo mere ser det jo ud som om det er det samme vi gør.. bortset fra du bruger closure som class scope..

function myClass(){
  var hej
function myClass(){
      hej = 10
      // dette er i min verden en constructor function
  }
myClass(); // bortset fra jeg ikke burde skulle kalde denne manuelt.. og defor er dette sikkert fuldstændigt en fuldstændig åndsvag fremgangs måde.. =P
}
Avatar billede olebole Juniormester
14. april 2012 - 22:35 #53
#51: Du opnår præcis det samme. Du opretter et object - og du kan ikke instantiere flere af samme slags. Der er ingen forskel på de to instanser, eller hvad de kan.

Normalt opretter new en ny instans af en klasse, men da din constructor er en anonym funktion i #45, kan du ikke oprette flere instanser. Når en instans er oprettet, er den bare et JS-object.

Spørger du f.eks. med:

alert(MySingleInstance instanceof Object);

- returneres i begge tilfælde true. Eneste forskel er:

alert(MySingleInstance.constructor);

Der er ingen forskel på deres opførsel/brug i øvrigt.

Indenfor din closure er du nødt til at 'klistre' constructoren fast på topobjektet, hvis den skal bruges i det globale scope. I en browser er det window objektet. I et andet miljø skal du bruge det aktuelle miljøs topobjekt.
Avatar billede olebole Juniormester
14. april 2012 - 22:41 #54
I stedet for window.MySingleInstance = i #50, kan du også skrive:

var MySingleInstance = (function(){
    function myFunc(){
        return 10
    }
   
    return MySingleInstance = {
        otherObj: "something",
        val: "hello",
        getStuff: function(){
            return myFunc()+45
        }
    };
})();

Så er du ikke tvunget til at kalde topobjektet
Avatar billede askalot Mester
14. april 2012 - 22:48 #55
i see.. jeg må lige lure lidt på det. =)

Nå..så fik jeg også din dag til at gå med det :P

Igen tusind tak for hjælpen..jeg er klogere nu. Jeg vil da meget gerne give en masse point..interesseret?
Avatar billede olebole Juniormester
14. april 2012 - 22:49 #56
Ellers tak, jeg samler ikke point  =)
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