Javascript: Calling object methods within that object
Solution 1
Well, from your first example:
var _obj = {
property: value,
method1: function() {
// do stuff
},
method2: function() {
// use property
var prop = this.property;
// call method1
this.method1();
}
};
That's what the this
value is for.
Now, what you cannot do is refer to a property of an "under construction" object from elsewhere in the object literal syntax. (It's hard to give an example because it's just not syntactically possible.) In cases where you want to do that, you do need one or more separate assignment statements.
Solution 2
Guess what? You are making simple stuff complex. Pointy's answer is good, but the prototype way is better for several reasons. That's why I am describing (rather, making corrections in) the last method. Check this fiddle.
var MyObj = function(name) {
this.name = name;
};
MyObj.prototype = {
called_often: function() {
// lots more code than just the following
return 'VALUE'; //document.getElementById('someID').value;
},
global_default: 'value', // can be changed, so need to pull value when run
does_stuff: function(value) {
var str = this.global_default + value, // can't access global_default on its own
input = this.called_often(), // doesn't work; MyObj.prototype.called_often() DOES
name = this.name; // 'this' used in the prototype doesn't work
// even within a created object
return name + input + str;
}
};
var obj = new MyObj('Bob');
Marcus Hughes
Updated on March 31, 2020Comments
-
Marcus Hughes about 4 years
What is the best design pattern for achieving the following (which doesn't work)?
var obj = (function() { // code defining private variables and methods var _obj = { property: value, method1: function() { // do stuff }, method2: function() { // use property var prop = _obj.property; // obviously doesn't work // call method1 obj.method1(); // "obj" not finished being defined yet! } }; // obviously now I could do... var prop = _obj.property; return _obj; })(); // and I could now do... obj.method1();
A variation which I think should work is
var obj = (function() { var property = value, method1 = function() { // do stuff }, method2 = function() { // use property var prop = property; // call method1 method1(); }, _obj = { property: property, method1: method1, method2: method2 }; return _obj; })();
Similarly, how does it work for objects meant to be created with the
new
operator? Within the constructor function itself you can writethis.method()
. But what if you want to keep the constructor small, only defining those things which will likely be customized upon creation, and then defining the rest in the prototype? (This seems to be the common pattern.) Can the properties / methods within the prototype interact in any way?var MyObj = function(name) { this.name = name; }; var obj = new MyObj('Bob'); MyObj.prototype = { called_often: function() { // lots more code than just the following return document.getElementById('someID').value; }, global_default: 'value', // can be changed, so need to pull value when run does_stuff: function(value) { var str = global_default + value, // can't access global_default on its own input = MyObj.called_often(), // doesn't work; MyObj.prototype.called_often() DOES name = this.name; // 'this' used in the prototype doesn't work // even within a created object return name + input + str; } };
I'm sure there's better ways to achieve my result whenever I run into this problem. This code isn't situation specific and just illustrates the general problem. So you won't be able to give me an alternative for those specific situations I run into. But maybe you can help my overall thinking.