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); }
source to share
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
source to share
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
.
source to share
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(...) }
source to share
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);
}
source to share