1

I want to make a sort of "shopping list" in JS. I'm having trouble accessing the object with the argument of a function.

shopList = {
  create: function createList(listName) {
    listName = {};
    listName["Banana"] = 2
  },

  output: function output(listName) {
    console.log(listName)
  },

};

shopList.create('list')
shopList.output('list')

When I run shopList.output 'list' is returned. How do I access the object over the argument? Hope this isn't a duplicate, been googling for hours now and didn't make any progress.

Tushar
  • 85,780
  • 21
  • 159
  • 179
Paul Etscheit
  • 493
  • 1
  • 6
  • 16
  • 'over the argument'? – ergonaut Oct 17 '15 at 19:11
  • Sorry english isn't my mother tongue. Like access it with the passed arguement. – Paul Etscheit Oct 17 '15 at 19:12
  • It might be better with an example output of what you want. – ergonaut Oct 17 '15 at 19:14
  • I just want to return the entire object in the terminal, so in this case 'banana: 2' should be returned – Paul Etscheit Oct 17 '15 at 19:15
  • `var shopList = { create: function createList(listName) { this.listName = {}; this.listName["Banana"] = 2 }, output: function output(listName) { console.log(this.listName) }, }; shopList.create('list'); shopList.output('list');` – Tushar Oct 17 '15 at 19:19
  • @Tushar Note that [dot notation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors) won't make use of the variable. It only uses the name of the identifier that follows it, so that property will always be `"listName"`. – Jonathan Lonowski Oct 17 '15 at 19:24

2 Answers2

5

If you want to be able to configure lists with dynamic names then you need to use bracket notation to create lists within this object. Like this:

var shopList = {
    create: function createList(listName) {
        this[listName] = {};
        this[listName]["Banana"] = 2
    },

    output: function output(listName) {
        return this[listName];
    }
};

shopList.create('list');
console.log(shopList.output('list'));

However, as pointed by @armchairdj in comments, it's better to create a container dedicated property to hold lists:

var shopList = {
    lists: {},

    create: function createList(listName) {
        this.lists[listName] = {};
        this.lists[listName]["Banana"] = 2
    },

    output: function output(listName) {
        return this.lists[listName];
    }
};
dfsq
  • 191,768
  • 25
  • 236
  • 258
2

If you want to avoid clobbering the methods of your showList object by naively adding arbitrary, user-supplied keys, you should create an internal namespace for your lists.

var shopList = {
  lists:  {},

  create: function (listName) {
    this.lists[listName] = this.lists[listName] || {};

    this.lists[listName].Banana = 2;
  },

  output: function (listName) {
    var list = this.lists[listName];

    if (!list) {
      return console.log('No list named ' + listName + ' found.');
    }

    console.log(list)
  }
};

shopList.create('output');
shopList.output('output');
shopList.create('foo');
shopList.output('foo');
shopList.output('bar');
armchairdj
  • 1,030
  • 11
  • 13