Avatar billede andreas13_fam Nybegynder
21. januar 2011 - 21:41 Der er 2 kommentarer og
1 løsning

this peger på window

KODE:

(function () {

    var foo = {
                   
        bar : function () {
            console.log(this);
        },
        whenIseeThisIAmHappy : true,
       
        runfunction : function (func) {
            func();
        }
    };
   
    foo.runfunction(foo.bar);

})();


Mit problem er at når jeg kalder funktionen foo.bar som jeg gør i eksemplet peger this på window objektet. Hvad jeg enlig vil have er at this peger på foo objektet. Som det normalt vil gøre hvis jeg skræv foo.bar();

Spøgsmålet er altså, hvordan for jeg this til at pege på foo, uden at skulde ud i at bruge call eller apply hvor jeg er nød til at skrive "foo.runfunction(foo.bar, foo);".

Bemærk desuden at dette er et meget simpelt eksempel. I det rigtige eksempel ligger runfunction ikke engang i samme objekt som bar().
Avatar billede tjens Nybegynder
22. januar 2011 - 01:04 #1
Denne artikel http://www.quirksmode.org/js/this.html beskriver at funktioner grundlæggende altid peger på window, med mindre de har en parent i dom-træet: Så for de elementet som this.

Selv en rigtig objektorienteret funktion bliver overstyret med dom-elementet, i følgende demo.

Kør den og bemærk at this.id skifter værdi efter objektets kontekst, når du klikker på det øverste element.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"    "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title></title>

<style type="text/css">
body     { font-family: sans-serif;}
#clickableId { border: 3px outset lightgray; width: 100px; padding: 5px; }
#debugDiv    { border: 1px solid red ;padding: 5px; width:200px;}
</style>

<script type="text/javascript">

function foo (I) {
        this.id = I;
        this.current = this;
        this.bar = function () {
            document.getElementById("debugDiv").appendChild(document.createElement('hr'));
            document.getElementById("debugDiv").appendChild(document.createTextNode(this.id));
        };
        this.runfunction = function (func) {
            (func)();
        };
};

var myFoo = new foo("ObjectInstance 1 Id");

window.onload = function (){
    myFoo.runfunction(myFoo.bar);
    myFoo.bar(); 
    document.getElementById("clickableId").onclick=myFoo.bar;
}
</script>
</head>
<body>
<div id="clickableId"> Do onClick</div>
<hr>
<div id="debugDiv">Debug:</div>
</body>
</html>

Det hjælper nok ikke på dit problem direkte, men det kan være du kommer på sporet, eller får dokumentere at det ikke kan laves som du forsøger, når det er javascript.
Avatar billede tjens Nybegynder
22. januar 2011 - 13:23 #2
Denne artikel beskriver problemet rigtig godt, og kommer med mulige løsninger:
http://justin.harmonize.fm/index.php/2009/09/an-introduction-to-javascripts-this/

Jeg har ændret ovenstående løsning til følgende foo function:
function foo (I) {
        this.id = I;
        var self = this;
        this.bar = function () {
            document.getElementById("debugDiv").appendChild(document.createElement('hr'));
            document.getElementById("debugDiv").appendChild(document.createTextNode("this.id: " + this.id));
            document.getElementById("debugDiv").appendChild(document.createElement('br'));
            document.getElementById("debugDiv").appendChild(document.createTextNode("self.id: " + self.id));
        };
        this.runfunction = function (func) {
            func();
        };
};

Det giver et spændende resultat, som kan testes her: http://tjens.dk/eksperten/929604/
Avatar billede andreas13_fam Nybegynder
22. januar 2011 - 13:43 #3
Tak for din hjælp, det er muligt at jeg skal have revurderet min lærdom, men jeg har altid lært at grunden til at fx:

var foo = function () {}

har this === window er fordi den bliver langt ned i window objektet. Den kan jo også kaldes via window.foo().

min løsning endte med at blive en anonym funktion:
foo.runfunction(function () { foo.bar() });

Du er velkommen til at ligge et svar.
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