I have this javascript object:
return {
AccDocs: {
query: function() {
...
},
deleteAndQuery: function() {
...
AccDocs.query(); //Error: AccDocs is not defined
}
}
}
But, it returns an error that says AccDocs is not defined.
How can I achieve something like this?
Variables and properties on objects are different things. You cannot access the property of an object without specifying which object you mean.
You can probably access it using the this keyword:
this.query();
Keeping in mind that the value of this will vary depending on how the function is called (when a.b.c.d.AccDocs.deleteAndQuery() is called, this inside deleteAndQuery will be AccDocs as it is the first object to the left of the last ., but if you were to first copy query to another variable and then call query(), pass it to setTimeout, or if you were to use call or apply then the value of this would change).
For more robustness (but less flexibility, since being able to change the context can be useful) you can store your object in a variable which you can access by name.
var AccDocs = {
query: function() {
...
},
deleteAndQuery: function() {
...
AccDocs.query();
}
};
return { AccDocs: AccDocs };
By using the this keyword:
return {
AccDocs: {
query: function() {
...
},
deleteAndQuery: function() {
...
this.query(); //Here
}
}
}
Related
I have a problem with the following code:
// At the beginning
var prog = {}
// some attributes of prog and other methods
// ...
prog.stateChange = function(state)
{
var functionOfState =
{
onState1: function()
{
// some code
},
onState2: function()
{
// some code
}
}['on'+state]()
}
Which purpose have these square brackets after the creation of the object functionOfState? Is this an array of possible methods?
Sorry, I'm a total newbie in JS and I haven't found any information about this.
I really appreciate any help.
This code does almost the same as:
var functionOfState =
{
onState1: function()
{
// some code
},
onState2: function()
{
// some code
}
}
functionOfState['on'+state]();
It simply creates an object which stores different functions. Then, it calls one of them according to the current value of state.
Maybe, this one will be even easier:
var functionOfState = {};
functionOfState['onState1'] = function() {
// someCode
};
functionOfState['onState2'] = function() {
// someCode
};
functionOfState['on'+state](); // when state is 'State2', 'onState2' will be called
The difference that in your code it doesn't store this object with functions, but calls it directly.
This is (not the most clear) way to extract field from an object.
in JS, the subscript operator ([]) can extract a property out of an object just like the dot operator (.), so the following expressions are equal:
var obj = { field : value };
obj.field == obj["field"]; //returns true
on your example an object with the fields onState1, onState2 is created. then, using the subscript operator the correct property is extract. it is equivilant on writing
prog.stateChange = function(state)
{
var temp =
{
onState1: function()
{
// some code
},
onState2: function()
{
// some code
}
};
var functionOfState = state == onState1 ? temp.onState1 : temp.onState2;
functionOfState();
}
This is not a legit way to extract a property/method out of an object. basically if someone changes the name of the method, the code breaks. it is much better to simply use a switch case.
This is a general programming question, not specific to this code example.
How do I detect whether a particular method was called or not from within a function?
Imagine you want to be able to tell whether a particular method was called so that you can change what you return based on that.
var turtle = function() {
var vars = {
name: "Shelly",
age: 103
};
this.actions = function() {
var methods = {
crawl: function() {
//etc...
},
mutate: function() {
//etc...
},
eat: function() {
//etc...
}
};
if (methodWasCalled) { // <- The part I don't know how to do
return methods;
} else {
return this;
}
};
if (methodWasCalled) { // <- The part I don't know how to do
return vars;
} else {
return this;
}
};
Based on the above example, someone could use: turtle() and get access to the 'vars' object, or they could use: turtle().mutate() and the turtle object would execute the block inside that function.
To get the caller access the arguments object.
alert("caller is " + arguments.callee.caller.toString());
Callee refers to the function being executed, in your case mutate. It has a property that references the caller.
Best thing for you to do is break out a debugging kit (I personally prefer Chrome/IE) and explore the object to see the full details of info you want to see.
I have an object, nested within a parent object. The inner object has 2 functions and one needs to call the other. I assumed I could call this.theFunction(), but that doesn't seem to be the case.
var views = {
settings: {
init: function() {
this.doSomething(withThing);
},
doSomething: function(with) {
// NEVER GETS CALLED
}
}
};
In this case, this seems to reference a DOMWindow rather than the views.settings object as I was expecting. What am I missing?
UPDATE
The views.settings.init() function is called as a callback. An external process calls template.init(view, views.settings.init);. The latter argument is a callback. Within template.init(), the callback is simply called as callback(). For clarity (hopefully), here's a snippet of how we get to views.settings.init:
template.init(view, views.settings.init);
var template: {
init: function() {
callback();
}
}
What would cause the context to get lost and what can I do to get it back so that this references the views.settings object?
Try doing this:
var views = {
settings: {
init: function() {
var withThing = 'withThing';
this.doSomething(withThing);
},
doSomething: function(withThing) {
// NEVER GETS CALLED
alert(withThing)
}
}
};
views.settings.init();
Here's a jsfiddle
So, I've started playing with using an object to help organize my functions. So instead of having to make super long function names, I can just have sub functions in an object with the same prefix.
In my example, I'm using 'get' as a prefix, so I could call subfunctions by doing get.function(); and get.otherfunction();. However, I want to also be able to set a "default" function for the get object, so I can just call get(); by itself and it runs a function (but I don't want that function to run if I'm calling one of the subfunctions).
Here is the code I have thus far:
var get = {
default: function() {
alert('default function');
},
secondary: function() {
alert('secondary function');
}
}
You want to make an ordinary function, then add other functions as properties:
var get = function() { ... };
get.secondary = function() { ... };
If you want to, you could also write
get.default = get;
Or
get.default = function() { return get(); };
So here's the object 'playerTurnObj'
function playerTurnObj(set_turn) {
this.playerTurn=set_turn;
function setTurn(turnToSet) {
this.playerTurn=turnToSet;
}
function getTurn() {
return this.playerTurn;
}
}
and here is what I'm doing with it
var turn = new playerTurnObj();
turn.setTurn(1);
so I try to make the script do the setTurn() method in playerTurnObj() to save a 'turn' in a game I'm making. The problem is, it does not do the turn.setTurn(1); part because I keep getting the error above
what am I doing wrong? I searched, but I could not find an exact answer to my question.
This is not the way JavaScript works. Your "constructor" function contains inline functions that are not visible outside of the scope of playerTurnObj. So your variable turn does not have a method setTurn defined, as the error message states correctly. Probably you want something like this:
function playerTurnObj(set_turn) {
this.playerTurn=set_turn;
}
playerTurnObj.prototype = {
setTurn: function(turnToSet) {
this.playerTurn=turnToSet;
},
getTurn: function() {
return this.playerTurn;
}
};
Now your variable turn has two methods setTurn and getTurn that operate on the instance you created with new.
The setTurn and getTurn functions are private so they return undefined rather than invoking the function. You can do:
function playerTurnObj(set_turn) {
this.playerTurn=set_turn;
this.setTurn = setTurn;
this.getTurn = getTurn;
function setTurn(turnToSet) {
this.playerTurn=turnToSet;
}
function getTurn() {
return this.playerTurn;
}
}
You then have public setTurn and getTurn methods and can invoke them as follows:
var turn = new playerTurnObj();
turn.setTurn(1);
http://jsfiddle.net/Ht688/
What I make out of it is you need to return the object this in function playerTurnObj(). So your new code will look something like:
function playerTurnObj(set_turn) {
this.playerTurn=set_turn;
function setTurn(turnToSet) {
this.playerTurn=turnToSet;
}
function getTurn() {
return this.playerTurn;
}
return this;
}