I have the following object:
var object = {
attr1 : "hello",
myFunc : function() {
alert(this.attr1); //This should alert "hello"
},
initialize : function() {
document.getElementById("myElem").addEventListener("click", function() {
// How do I access attr1 from here?
myFunc(); // Says myFunc is not defined.
});
}
}
object.initialize();
How do I access myFunc or attr1 from inside of the anonymous function passed to addEventListener?
One way I can think of is this:
var object = {
attr1 : "hello",
myFunc : function() {
alert(this.attr1); //This should alert "hello"
},
initialize : function() {
myObject = this;
document.getElementById("myElem").addEventListener("click", function() {
// How do I access attr1 from here?
alert(myObject.attr1);
// calling myFunc
myObject.myFunc();
});
}
}
object.initialize();
But is this a good solution?
Also, If I do this:
var object = {
attr1 : "hello",
myFunc : function() {
alert(this.attr1); //This should alert "hello"
},
initialize : function() {
myFunction = this.myFunc;
document.getElementById("myElem").addEventListener("click", function() {
// How do I access attr1 from here?
alert(myObject.attr1);
// calling myFunc
myFunction();
});
}
}
object.initialize();
Then it alerts with "undefined". Which means this.attr1 is undefined.
Why so?
Inside your event handler function, this will always refer to the DOM element on which the event has been attached.
To access the object properties, you need to use the alternatives such as self/that.
initialize : function() {
var that = this;
document.getElementById("myElem").addEventListener("click", function() {
alert(that.attr1);
that.myFunc();
});
}
In your solution, you have declared myObject globally as var is missing.
var object = {
attr1 : "hello",
myFunc : function() {
alert("Instance of window ? "+(this instanceof Window));
alert(this.attr1); //This should alert "hello"
},
initialize : function() {
myFunction = this.myFunc;
document.getElementById("myElem").addEventListener("click", function() {
// How do I access attr1 from here?
alert(object.attr1);
// calling myFunc
myFunction();
});
}
}
object.initialize();
<div id="myElem">Click me</div>
Now as you can see in the alert, this refers to the window object. Because when you copy the function, its by value and not by reference. So only the function is copied and not underlying object. So now this will refer to the window object.
The solution you provided is exactly how I go about solving this issue, declare a variable and set its value to this, then use that to call other functions within your object.
otherFunc: function() {
console.log('test');
},
myFunc: function() {
var self = this;
// do stuff
// call other function
self.otherFunc();
}
Just make it like this - >
You do not need extra variables to make your code so obscure. :)
var object = {
attr1: "hello",
myFunc: function () {
alert(this.attr1); //This should alert "hello"
},
initialize: function () {
document.getElementById("myElem").addEventListener("click", function () {
// How do I access attr1 from here?
object.myFunc();
});
}
}
object.initialize();
Related
var obj = {
someFunc : function() {
console.log("Hello");
console.log(this);
var obj1 = {
someFunc1 : function() {
console.log("Hi");
}
};
}
};
obj.someFunc();
obj.obj1.someFunc1();
I have just created an object. And inside an object, a method, and then a new object and obj1. I am just trying to check 'this' keyword. But, it seem to me it's grammatical error in js. That is not possible. Right? But, why?
var obj = {
someFunc : function() {
console.log("Hello");
console.log(this);
return {
someFunc1 : function() {
console.log("Hi");
}
};
}
};
obj.someFunc().someFunc1();
Given the following how do i enable this to work correct?
return {
methodA: function() {
return methodB();
},
methodB: function() {
alert("hi");
}
}
You need to reference the context, via this.
var foo = {
methodA: function() {
return this.methodB(); //context
},
methodB: function() {
alert("hi");
}
}
foo.methodA(); //alerts "hi"
It seems you are returning from a module like function. The safe way is not to use this, it is to keep a reference to the object so that it won't matter how the function is called.
function getObj() {
var obj = {
methodA: function() {
return obj.methodB();
},
methodB: function() {
alert("hi");
}
};
return obj;
}
var myObj = getObj();
// Works
myObj.methodA();
// Works but would not work if you were using `this` as suggested by Utkanos.
someDomElement.addEventListener('click', myObj.methodA);
I have this simple Javascript object that calls its own prototype method in one of its local methods. [SEE MY EDIT]
var Obj = function() {
function inner() {
this.exported();
}
this.exported = function() {
alert("yay!");
};
};
var test = new Obj();
Obj.exported();
However, I get the error TypeError: Object function() {...} has no method 'exported'.
Any idea how this should be done?
EDIT:
whoops, just realized I never called inner(), but thanks Patrick for answering that part anyways. Here is a better example
var Obj = function() {
this.exported = function() {
inner();
};
function inner() {
this.yay();
}
this.yay = function() {
alert("yay!");
};
};
var test = new Obj();
test.exported();
I get TypeError: Object [object global] has no method 'exported'
should be used
test.exported();
instead of
Obj.exported();
You should invoked exported() method over the test object, not over the Obj constructor.
UPDATE
After reached inside the function inner(){...}. this is refers to global window not Obj, so pass the actual object this from inner(this) and do invoke export() from that passed object into function inner(cthis){...}, something like.
function inner(cthis) {
//----------^--get Obj on here
cthis.exported();
}
this.exported2 = function() {
inner(this);
//------^--pass Obj from here
};
DEMO
to call exported you need to call it off the variable you assigned the instance to:
test.exported();
Also for the inner function you cannot use this there to access the Obj object as it refers to window.
save a reference to this and then use that to call the function
var Obj = function() {
var _this = this;
function inner() {
_this.exported();
}
this.exported = function() {
alert("yay!");
};
};
Here is a simplified version of my JS:
var myObject = function() {
return {
functionOne: function() {
//some other logic here
},
functionTwo: function() {
var self = this;
//some logic here
//then call functionOne
self.functionOne();
}
};
}
Then I have this in the body of my html:
click me
Why do I get the error Uncaught TypeError: Object [some url] has no method 'functionOne', when I click the link?
The error that you're seeing doesn't reflect the example code you've shown.
That said, in the way that you're using the code, you should be able to reduce it to simply:
var myObject = {
functionOne: function() {
},
functionTwo: function() {
this.functionOne();
}
}
Your myObject is a function that needs to be called in order to get that object
click me
Why not just define myObject as an object:
var myObject = {
functionOne: function() {
//some other logic here
},
functionTwo: function() {
var self = this;
//some logic here
//then call functionOne
self.functionOne();
}
};
What you need is for your function to be executed immediately. Further to that your declarion of the self variable leads me to think that you are trying to create a closure so that you can access functionOne from functionTwo. If that is the case then I think the following is what you were after:
var myObject = (function() {
function func1( ) {
}
function func2( ) {
func1();
}
return {
functionOne: func1,
functionTwo: func2
};
}());
I'm just getting started in OO javascript so please bear with me.
This works:
var myObj = {
foo : function() {
alert('hello');
this.bar();
},
bar: function() {
alert('world');
}
}
However if I do some other stuff after the hello alert in the "foo" method then the meaning of "this" changes from the object to whatever I last selected so using this.bar() doesn't execute the other method in the class.
So I tried to cache "this" in a variable like so:
var myObj = {
publicVars: {
theObj : this
},
foo : function() {
alert('hello');
publicVars.theObj.bar();
},
bar: function() {
alert('world');
}
}
But that didn't work either. So what is the solution?
EDIT
Here is my actual code:
var formObj = {
validate : function(theForm) {
$('input, textarea', theForm).each(function() {
var valueLength = $(this).val().length;
if (valueLength === 0) {
$(this).addClass('invalid');
this.listenForInput($(this)); // <!------- this isn't working
}
});
},
listenForInput : function(theField) {
// theField.keyup(function() {
// if ($(this).val().length > 0) {
// theField.removeClass('invalid');
// }
// });
alert('I work!!!!');
}
} // end obj
As I said in my comment, you have to keep a reference inside the function:
validate: function(theForm) {
var self = this;
$('input, textarea', theForm).each(function() {
var valueLength = $(this).val().length;
if (valueLength === 0) {
$(this).addClass('invalid');
self.listenForInput($(this));
}
});
},
You are passing a function to each. Inside this callback, this refers to the DOM element. That's why you pass it to jQuery ($(this)) to be able to call jQuery methods on that element. It cannot refer to formObj too!
What this refers to is determined by how a function is called and each function has its own this (the Mozilla documention describes this in more detail).
If you call validate with formObj.validate(), then this refers to formObj.
The jQuery documentation for each states:
More importantly, the callback is fired in the context of the current DOM element, so the keyword this refers to the element.
Am I missing something, or can you not just reference the object by name, like this:
var myObj = {
foo: function() {
alert('hello');
myObj.bar();
},
bar: function() {
alert('world');
}
}
myObj.foo();
http://jsfiddle.net/karim79/kaXYj/
A function's this keyword is set by the call, it can't change during function execution.
Calling obj.foo() sets foo's this to obj so calling this.bar calls obj.bar. However, if you call foo some other way, e.g.:
var a = obj.foo;
a();
then its this will may be obj (in the above case it will be window or undefined in strict mode) so you get a different bar or an error if the this object doesn't have a bar property.