I'd like my code to look something like this, but I don't know how to make that happen.
var employee = namespace.employee(2); // return object
var employeeName = namespace.employee(2).name; // return string
var name = employee.name;
I was thinking of creating a namespace like this
var namespace = (function(){
})();
And then putting like classes inside it, I just don't quite know where to start.
This is all you need to implement that behaviour:
var namespace = {};
namespace.employee = function (num) {
return { name: num };
};
The function employee on the object namespace which returns an object containing the key name.
Assuming you want something like a repository of employees and the num tells it which employee to return:
var namespace = {};
var employees = [{ name: 'Joe' }, ...];
namespace.employee = function (num) {
return employees[num];
};
Assuming you want the employees repository to not be globally accessible:
var namespace = {};
namespace.employee = (function () {
var employees = [{ name: 'Joe' }, ...];
return function (num) {
return employees[num];
};
})();
Related
I have an array of objects inside an object.
Why do I get the error 'Cannot read property fname of undefined' below? How do I fix it?
Also, I'm new to javascript and would appreciate any styling or convention suggestions.
https://jsfiddle.net/go1eu9z6/
function myObj() {
this.X = [],
this.haveEntries = function() {
return this.A.length > 0;
},
this.add = function(fname_in, lname_in, city_in) {
var t = new Date().getTime() / 1000;
var obj = {
fname: fname_in,
lname: lname_in,
city: city_in,
t_create: t
};
this.X.push(obj);
return this;
}
}
var AB = {};
AB.X = new myObj();
AB.X.add("mike", 'smith', 'Toronto');
var s = AB.X[0].fname; // Error: Cannot read property fname of undefined
document.getElementById('fname').innerHTML = s
There were a couple problems with your javascript code. Firstly, you were assigning AB.X a value of new Obj() instead of simply AB. Then, you were calling the add method on AB.X, when the correct call would simply be AB.add - see code example below
function myObj() {
this.X = [],
this.haveEntries = function() {
return this.A.length > 0;
},
this.add = function(fname_in, lname_in, city_in) {
var t = new Date().getTime() / 1000;
var obj = {
fname: fname_in,
lname: lname_in,
city: city_in,
t_create: t
};
this.X.push(obj);
return this;
}
}
var AB = {};
AB = new myObj();
AB.add("mike", 'smith', 'Toronto');
var s = AB.X[0].fname;
with you existing code you can also access it by using
var s = AB.X.X[0].fname;
You don't need to make X an instance of myObj. In fact, that's what's breaking your code. X is created when you make a new instance of myObject, like this:
var AB = new myObject();
Then you would be calling your add() method on this AB object, not on X:
AB.add('mike','smith','toronto');
Finally, you would get your results like this:
var firstName = AB.X[0].fname;
This is a little round-about why of constructing this object, though. How do you know which person's name and info occur at which index of X? Maybe look into using an object to store this data with some key that helps you know where stuff is. Might look like:
var people = {
"uniqueID": { // some uniqueID
"fname":"mike",
"lname":"smith",
"city":"toronto"
}
}
I want to dynamically call a function from a string like "User.find". A script would call the function find() in the object User if the function exists. Here's what I tried:
var User = {};
User.find = function(){
return 1;
}
var input = 'User.find';
var some_data_array = {name: 'John Doe'};
var method = input.toString().split('.');
var nameObj = method[0].substring(0,1).toUpperCase() + method[0].substring(1);
var methodToCall = method[1];
nameObj.call(methodToCall, some_data_array);
But it always returns:
nameObj.call(methodToCall, some_data_array);
TypeError: Object User has no method 'call'
Any idea? I can't use window since it is a node.js problem, the script is not executed in the browser.
You're completely misunderstanding call().
call() lets you call a method with a different this.
You want to get as property by name:
object[methodName](arg1, arg, ...);
You actually can achieve this. You first would need to get the scope, where your namespace/function/object is defined.
For example, in your code I would assume its window.
So, a little modification of your code would produce the desired result:
var User = {};
User.find = function(x){
alert(x);
}
var input = 'User.find';
var some_data_array = {name: 'John Doe'};
var method = input.toString().split('.');
var nameObj = global[method[0]];
var methodToCall = method[1];
nameObj[methodToCall](some_data_array.name);
Mark the use of global[]. This is where it starts.
[edited] * Modified code to use global instead of window as being used in nodejs.
What you want to do is access the global object.
This should work:
var User = {};
User.find = function(){
return 1;
}
var input = 'User.find';
var some_data_array = {name: 'John Doe'};
var method = input.toString().split('.');
var nameObj = method[0].substring(0,1).toUpperCase() +method[0].substring(1);
var methodToCall = method[1];
"use strict";
var global = (1,eval)("this");
alert(global[nameObj][methodToCall](some_data_array));
There are a couple of ways to get the desired result. In this case it is very simple to just use an anonymous function, as follows, passing in the string parameter contained in objName.name:
var f = function(oName){
if (oName == 'John Doe') {
return 1;
}
};
var objName = {name: 'John Doe'};
console.log( f( objName.name ) );
If the OP prefers to use an object's call method, the following code also will suffice:
var myObj = {
myFunc: function() {
if (this.name == 'John Doe') {
return 1;
}
}
}
var objName = {
name: 'John Doe'
};
console.log(myObj.myFunc.call(objName));
A couple of things to note. myObj calls its method myFunc() passing in the object parameter objName. The purpose of this in the method is to read the property name, possessing that ability because of being bound to the object objName.
I am trying to set some variable to an object. But i want it to be set like the code below
is there a way to set a variable like this?
myObject = {};
myObject.save = function (var) {
console.log(var);
}
myObject.users.save(); // must output 'users';
myObject.fruits.save(); // output fruit;
the save method is just an example method. it means that i need to chain a method on the variable string.
i trying to achieve something like that.
any ideas how to achieve that?
thanks
You can create a List class for your users and fruits lists, and provide regular list methods like add, remove, size and etc. to make it actually like a list class, and define your save method as a prototype method:
var List = (function(){
function List(listType){
this.listType = listType;
this._list = [];
}
List.prototype.add = function(item){
this._list.push(item);
};
List.prototype.size = function(item){
return this._list.length;
};
List.prototype.save = function(item){
console.log(this.listType);
};
return List;
})();
then you can use it in your object like:
var myObject = {};
myObject.users = new List("users");
myObject.fruits = new List("fruits");
now you can actually call those two lines of code:
myObject.users.save(); // output 'users';
myObject.fruits.save(); // output 'fruits';
and you can also define a save method for myObject and actually call the lists save method:
myObject.save = function(listType){
if(myObject[listType] instanceof List){
myObject[listType].save();
}
else{
console.log("there is no such a list named : " + listType);
}
};
and call it like:
myObject.save("users");
myObject.save("fruits");
You can do like
var obj = {
users: {
save: function () {
console.log('Users');
}
},
fruits: {
save: function () {
console.log('Fruits');
}
},
}
(or)
var obj = {};
obj.users = {};
obj.users.save = function () {
console.log('Users');
};
obj.fruits = {};
obj.fruits.save = function () {
console.log('Fruits');
};
In Google Apps JS. I would like to implement an array of objects, each with properties and methods. One of the properties needs to be an array of objects and I would like to be able to access this array by using methods in the parent array.
So far my best efforts is:
function myFunction () {
var teamNo = 3;
var allNames =["n1","n2","n3","n4"] ;
var createnames = function () {
var names = [];
for ( var j = 0; j <=3 ; j ++) {
(function (j) {
var localNames = ["local1-names"+j,"local2-names"+j];
names[j] = (function (player){
return {
namArr: localNames,
name: allNames[j],
addName: (function (player){
localNames.push(player);
}) (player),
team: teamNo
};
});
}) (j);
}
return names;
}
var myname = createnames();
var foo = myname[0]().namArr;
var foo1 = myname[1]().namArr;
myname[1]().addName("added");
var foo2 = myname[1]().namArr;
var foo3 = myname[2]().namArr;
var debug = true;
}
As soo as I add the code to implement the sub array I get a runtime error saying that addName does not exist.
You're invoking this immediately:
addName: (function (player) {
localNames.push(player);
})(player)
instead of assigning it:
addName: function (player) {
localNames.push(player);
}
Also, each names[] function takes a player, and so does the addPlayer() function, making the names[] parameter unreachable. If you're not going to pass anything to the names[] functions, then remove the parameter.
And I'd suggest using named functions instead of inlined IIFEs.
I need to migrate a code in java to javascript.
In java, I am maintaining a hashmap with key = string and value = arraylist of objects
I need to implement the same in javascript:
this.hashMap = new Hash();
this.hashMapArrayList =[];
...
var hashMapDataSet = new HashMapDataSet(id1,name1,type1);
this.hashMapArrayList[0] = hashMapDataSet;
...
this.hashMap.set(fileName1, this.hashMapArrayList);
var hashMapDataSet1= new HashMapDataSet(id2,name2,type2);
this.hashMapArrayList[0] = hashMapDataSet1;
this.hashMap.set(fileName2, this.hashMapArrayList);
But when I try to get the properties for a specified key
this.hashMap.get(fileName1).getId()
I get the value= id2 which is the last id that was set for HashMapDataSet object.
I have tried to mimic getters and setters in javascript as specified in the following link:
http://javascript.crockford.com/private.html
Here is the HashMapDataSet class
function HashMapDataSet(pId, pName, pType) {
var id = pId;
var name = pName;
var type = pType;
function getId1() {
return id;
}
function setId1(mId) {
id = mId;
}
....
this.getId = function () {
return getId1();
};
this.setId = function (id) {
setId1(id);
};
...
}
where getId1, setId1 are private methods and
getId, setId are priviledged methods
I am new to javascript, so I am unable to correlate java object with javascript. Kindly help.
I'm not quite sure what you're trying to do there, but in javascript you don't need all this java wiring, because the language has built-in maps and lists. Your snippet can look like this in js
this.hashMap = {};
this.hashMapArrayList =[];
...
this.hashMapArrayList.push({id: id1, name: name1, type: type1});
...
this.hashMap.fileName1 = this.hashMapArrayList;
this.hashMapArrayList.push({id: id2, name: name2, type: type2 });
this.hashMap.fileName2 = this.hashMapArrayList;
The javascript-closure-loop problem is very common.
I would take a lot to: http://www.javascriptkata.com/2007/04/11/a-common-problem-with-the-powerful-javascript-closures/
Regards.
for the class you needn't private functions, you can use directly privileged functions:
function HashMapDataSet(pId, pName, pType)
{
var id = pId;
var name = pName;
var type = pType;
this.getId = function ()
{
return id;
};
this.setId = function (pId)
{
id = pId;
}
}