I don't understand why the "this" keyword doesn't work as I expect

What I want to do is execute the create_tag function when the specified condition is met. I mean this function as a method of an object, in this case document.body, setting the external function "create_tag (..)" as my method. The problem is inside this function. I have the keyword "this" which I expect with a reference to the parent method, document.body. Instead, it doesn't work. I tried to replace "this" with "document.body" in the function, so the problem must be called "this".
Here is the code:

xmlDom=xmlhttp.responseXML;
hint_ul=document.getElementById("hint_ul");
personaggi=xmlDom.documentElement.getElementsByTagName("personaggio");
for(i=0;i<personaggi.length;i++){
    personaggio=personaggi.item(i);
    name=personaggio.childNodes[1].firstChild.nodeValue;
        if(name.substr(0, str.length).toLowerCase()==str.toLowerCase()){
            document.body.crea_li=create_tag(name);
        }
}
}


function create_tag(inner){
a=document.createElement("a");
a.innerHTML=inner;
this.appendChild(a); }

      

+3


source to share


5 answers


this

will be window

when called like this.

To get it this

as an element body

, call it like this ...



document.body.crea_li = create_tag.call(document.body, name);

      

+1


source


You can refer to this

outside of the function body - by referencing it within scope later:

var self = this;
function create_tag(inner){
    a=document.createElement("a");
    a.innerHTML=inner;
    self.appendChild(a); 
}

      


This might be a good trick. When I make complex javascript objects involving many objects and functions, at the top of the object I create:



var self = this;

      

since it will be in scope, the root object is always available.

Here is a working example of how I would implement this:

SomeReallyComplexThing = function() {

    var self = this;
    var foo = 'bar'

    this.fooThing = 'Other thing'

    this.setSomeData = function(){
        console.log('Some data set', arguments)
    }

    this.makeMassiveCall = function() {
        var completeFunc = function(){};
        var url = '/some/endpoint.json';
        var requestData = {};

        jQuery.get(url, requestData, function(data) {

            /*
            * Data has come back
            */
            self.setSomeData(data)
            completeFunc(data);                  
    });

    }

}

//outside the scope
s = new SomeReallyComplexThing()
s.fooThing() //visible
s.self //undefined

      

+1


source


There is create_tag

no method assigned anywhere in your code document.body

. The closest you get is a string document.body.crea_li=create_tag(name);

, but what actually happens here is what you are doing create_tag

as a member of the global object and the result of that operation is being assigned document.body.crea_li

.

+1


source


this

There is a sqirrely guy in javascript. The idea this

refers to the current context of the function.

This means that when your executable code inside a function this

refers to that function context that has no method appendChild

.

Usually you use closure to keep a reference to the calling context, something like this

var _self = this;

var result = func();

function func()
{
    // _self is the calling context, this is the current context
}

      

Or you can pass a reference to the calling context:

document.body.crea_li=create_tag(name,this);



function create_tag(inner, context) { context.body.appendChild(...) }

      

0


source


this

refers to a parent function, but its parent is an object window

, not an object document

or document.body

. this

actually refers to whatever context the function is called from, and in my opinion you should avoid using it to call methods for this very reason, because it can be difficult to figure out what you really mean this

. For example, if you called a function using this

from another function, it would refer to the context within that function.

This example can help show what's going on:

var hello = function() {
    alert( this.message );
}
window.message = "hello!";
hello()

      

You could be document.body

directly in the code as before, or you could pass another parameter that tells the function where the generated tag can be added:

function create_tag(inner, elementToAddTag){
  a=document.createElement("a");
  a.innerHTML=inner; 
  elementToAddTagTo.appendChild(a); 
}

      

0


source







All Articles