I've created a javascript object
var Article = function(data) {
this.foo = data,
this.get_more_data = function() {
// do something, get a response
show_data(response);
},
this.show_data = function(bar) {
//do something with bar;
}
};
which works fine when the method show_data is written without this. but then it isn't accessible outside of the object. With this. I get a "Uncaught ReferenceError" from the Chrome console.
Why is this?
Thanks.
You should be calling show_data as a method of this, not as a function scoped to the current context:
var Article = function(data) {
this.foo = data,
this.get_more_data = function() {
// do something, get a response
this.show_data(this.foo);
},
this.show_data = function(bar) {
console.log(bar);
}
};
Related
I have JS object
var widget = {
check_balance: function(){...},
function_called_in_init: function(){
.....
this.check_balance();
};
};
this is code screenshot for better understanding..
and when it try to call this.check_balance(); it returns me error TypeError: this.check_balanceis not a function
the question would be - how to call function inside object which was also created inside object?
Also I can't init this function at the moment when all object is inited, becouse this is a recursion with ajax callback.
Its a little tricky to see what you are asking but the gist of it is you are looking to have the correct context. The tool for that is the whatever.bind(theContext) function. You pass in theContext to the object and that makes theContext object the context of whatever.
var parent = {
foo: function () {
var widget = {
check_balance: function(){ console.log('checking'); },
function_called_in_init: function(){
this.bar();
}.bind(this),
};
widget.function_called_in_init();
},
bar: function () {
console.log('bar');
},
};
parent.foo();
see fiddle
bind documentation
Use private function and closure
var widget = (function() {
var check_balance = function() {
//do what your check_balance has to do
}
return {
check_balance: check_balance,
function_called_in_init: function(){
.....
check_balance();
};
};
})();
I have the following code:
var tradingInterface = function() {
this.json = '';
this.init = function() {
$.get( '/whatever',{}, function(data) {
this.json = data;
// Rebuilds Everything
this.rebuildAll();
});
};
this.rebuildAll = function() {
//whatever here
};
};
Why am I getting in init function the following error?
ReferenceError: this.rebuildAll is not defined
this.rebuildAll();
Why can I access to this.json without scoping problems but not to this.rebuildAll?
I wrote a similar previous thread but i was redirected to How to access the correct `this` / context inside a callback? but i am not able to make it work properly.
As thw thread suggets, I tried with:
var tradingInterface = function() {
this.json = '';
var self = this;
this.init = function() {
$.get( '/whatever',{}, function(data) {
this.json = data;
// Rebuilds Everything
self.rebuildAll();
});
};
this.rebuildAll = function() {
//whatever here
};
};
The error disappears but rebuildAll function is not doing what it should...
I need some help...
Regards,
The error disappears but rebuildAll function is not doing what it should...
You are not explaining what the rebuildAll is supposed to do, so I can only assume that the issue is that you didn't replace
this.json = data;
with
self.json = data;
Inside the the $.get callback, this refers to a different object than self. This is all explained in the question/answer you linked to.
Why can I access to this.json without scoping problems but not to this.rebuildAll?
You are assigning to this.json. You can (almost) always assign a property to an object. However, you are reading this.rebuildAll and try to call it as a function. Since this.rebuildAll is undefined, you cannot call it.
Simplified example:
var obj = {};
obj.foo = 42; // works, foo didn't exist before
obj.bar = function() {}; // works, bar didn't exist before
obj.bar(); // works because bar exists
obj.baz(); // doesn't work, because baz doesn't exist
I tried execute this code:
var system = new Object();
(function($) {
$.init = function() {
var o = {
message: function(arg) {
return arg.val;
},
alert: this.message({
val: "Hello, world."
})
};
return o.alert;
};
})(system);
alert(system.init());
but, when I execute it I get error message which tells me that this.message is not a function. Obviously, this not refers to object o itself, and I want to know why.
I found few solutions on stackoverflow where this is always inside function body, but why this can not be outside? Thanks.
Change your code to:
var system = new Object();
(function($) {
$.init = function() {
var o = {
message: function(arg) {
return arg.val;
}
};
o.alert = o.message({
val: "Hello, world."
});
return o.alert;
};
})(system);
system.init()
Yields:
"Hello, world."
In your code this would refer to window in that context. If you want to create an object and refer to it as this - use constructor function, i.e.:
var o = new function(){
...
<here: this == o>
...
}
You can use an anonymous constructor function instead of object literal syntax if you want to reference the object during instantiation.
(function($) {
$.init = function() {
// -----vvv---vvv---constructor function
var o = new function() {
this.message = function(arg) {
return arg.val;
},
this.alert = this.message({
val: "Hello, world."
})
};
return o.alert;
};
})(system);
Because the value of this is only defined within a function when the function is invoked, object literal syntax never changes its value.
So instead we create a function, and invoke it using new so that the value of this in the function is a reference to the new object we're building.
And of course it doesn't need to be anonymous, but if you're only going to use it once, there's no need for a name.
All, I am struggling with an error which says TypeError: curTemplete.addSection is not a function, Please forgive that I am not familiar with the js OO, Please help to review my problem. thanks.
The code looks like below.
Templete.js
LayoutTemplete=function(currentTmpContainer,templeteId,data)
{
var curTemplete = this;
curTemplete.addSection(null, null);//this line run with error above.
this.addSection = function(uiItem, data) {
alert('ddd');
};
};
In the dom ready event.
function loadTempleteContent(templeteId)
{
var jData=[{name: 'jerry'},{name: 'mike'},{name: 'claire'}];
var tmp = new LayoutTemplete($("#currentTmpContainer"),templeteId,jData);
}
You cannot call a function before it was defined. This has nothing to do with OOP. Consider this example:
foo();
var foo = function() {
alert(42);
};
It will throw a similar error.
Define the function/the property before you access it:
this.addSection = function(uiItem, data) {
alert('ddd');
};
this.addSection(null, null);
Better yet, define addSection on the prototype, so that you don't create a new function every time you create an instances of LayoutTemplete.
LayoutTemplete = function(currentTmpContainer,templeteId,data) {
this.addSection(null, null);
};
LayoutTemplete.prototype.addSection = function(uiItem, data) {
alert('ddd');
};
Felix is trying to tell you what your issue is, here it is explicitly:
var curTemplete = this;
curTemplete.addSection(null, null);//this line run with error above.
Here you reference and attempt to call curTemplete.addection, which has not been assigned a value yet, so it resolves to undefined. When the call is attempted, undefined is not a function (as the error tells you). addSection is not defined until the assignment below:
this.addSection = function(uiItem, data) {
alert('ddd');
};
Now it's defined. Move the assignment before the call (and if you're going to assign this to a local variable, you may as well use it):
var curTemplete = this;
curTemplete.addSection = function(uiItem, data) {
alert('ddd');
};
curTemplete.addSection(null, null);
I am using the module pattern like:
BLAH = ( function() {
var someMethod = function(data) {
};
return {
someMethod: function(data) {
this.someMethod(data);
}
}
})();
Inside the public someMothod, is it good practise to reference the inner function using this?
Does it matter or it's just makes things clearer?
For more clarity, the above code could be written:
var Blah = (function(){
Blah = function() {
};
Blah.prototype.someMethod = function( data ){
...
}
return Blah;
)();
Cheers!
Your example does not work as expected. When BLAH.someMethod() is called,
someMethod: function(data) {
this.someMethod(data);
}
it will keep calling the public someMethod recursively until there's a stack overflow.
To access the private function, you should not prefix it with this.. The private function is not a property of the current object. It is only available in the execution context of someMethod.
It's just a convention to make your code more readable (which shouldn't be undervalued). Doesn't make a difference from a functionality standpoint.
Personally I'm not sure what you gain from having the private inner method.
This is the template I use for my projects, it's based on how jQuery does theirs.
(function ($, undefined) {
var MyObject = (function () {
var myObj = {},
_myInternalVariable = 'YAY';
//Internal method
function _internalMethod(){
};
//external variables
myObj.debug = false;
//version number
myObj.version = "1.0";
// Logs the message to the console, if it (the console) exists
myObj.log = function (msg) {
if (window.console && typeof console.log !== "undefined" && myObj.debug) {
console.log(msg);
}
};
return myObj;
})();
window.MyObject = window.MO = MyObject ;
})(jQuery);