0

I am having a hard time describing my case, so forgive me if this is resolved before.

I want to define an object in the following way:

var foo = [
   {
      firstName : 'John',
      lastName : 'Doe',
      fullName : this.firstName + this.lastName
   },
    // OR
   {
      firstName : 'Jane',
      lastName : 'Doe',
      herID : Do-something with the first and last name that were just defined, such as computeCombination(firstName, lastName)
   }
]

Is this kind of declaration possible?

I need to finish the declaration of foo at once and here, I cannot make changes to the object later. Moreover, I don't want to get involved with indexes here, such as using foo[0].firstName etc..

Main reason I want this is that, I do not want to write same strings again, because it is redundant and strings are pretty lengthy. Also, each object in the array might have a different combinational logic for the last key.

Thank you

batilc
  • 691
  • 1
  • 5
  • 16
  • No, it is not possible. – Alexander O'Mara Jan 24 '15 at 16:57
  • what would you suggest for achieving similar to this kind of declaration? – batilc Jan 24 '15 at 16:59
  • Depends, does each object have a different set of properties? – Alexander O'Mara Jan 24 '15 at 17:00
  • No, in my application they all have one common property, suppose it is named 'title'. Then the title is used for creation of another object. like: myJournal : new Journal(title); Title is always a string. – batilc Jan 24 '15 at 17:06
  • You can assign to object properties any expression that will return a value. Looks simple to me, am I missing out on something? For me your code works perfectly, as long as computeCombination is a function that returns a value. And if it doesn't, you can always modify it, or wrap it into another one that will return value. – CodeVirtuoso Jan 24 '15 at 17:14
  • 1
    @Freelancer - the problem is that you can't refer to `this.firstName` or `this.lastName` in a static declaration such as the OP is using. That doesn't work because `this` is not set to the object in the static declaration. That's why my answer suggested using a constructor where you can use `this` that compute values based on other properties of the object. – jfriend00 Jan 24 '15 at 17:16
  • The problem is accessing the first and last names that were defined a sec ago. If I can reach them, then it should work just fine as you said – batilc Jan 24 '15 at 17:17
  • @batilc - you don't seem to understand what we've said several times now. You can't reach the properties just previously defined as part of the same object in a static declaration. You CAN'T. `this` is not set to point to the object and the parent variable declaration has not been finished yet so there is no way to access them. This is a limitation of static declarations. – jfriend00 Jan 24 '15 at 17:29

2 Answers2

3

It is possible using getters.

var foo = [ 
   {
      firstName : 'John',
      lastName : 'Doe',
      get fullName(){ return this.firstName +' '+ this.lastName; }
   }]


console.log( foo[0].fullName ); //John Doe

http://jsfiddle.net/6jq8ky0k/1/

pawel
  • 35,827
  • 7
  • 56
  • 53
  • Why is this better than using a constructor? This code isn't reusable like a constructor is. – jfriend00 Jan 24 '15 at 17:25
  • From the question: "*Also, each object in the array might have a different combinational logic for the last key.*" so reusability may not be the key concern here. – pawel Jan 24 '15 at 17:30
0

You can't do what you're asking with a "static" declaration like you show because this is not set to the object in a static declaration so you can't refer to other properties of the object using this, but if you want the same logic for making the fullName property, you can do it with a dynamic declaration using a constructor like this:

function Person(firstName, lastName) {
   this.firstName = firstName;
   this.lastName = lastName;
   this.fullName = firstName + " " + this.lastName;
}

var people = [new Person("John", "Doe"), new Person("Jane", "Doe")];

If you want different logic for each entry, then you can pass a callback into the Person() constructor that defines the logic to use like this:

function Person(firstName, lastName, fn) {
   this.firstName = firstName;
   this.lastName = lastName;
   this.fullName = fn(firstName, lastName);
}

function combine(f, l) { return f + " " + l;}
function makeID(f, l) {return f.slice(0, 1) + l;}

var people = [new Person("John", "Doe", combine), new Person("Jane", "Doe", makeID)];

Or, if you really want different things for other properties, then maybe everything in the array isn't the same type of object so you could use different constructors when you wanted something different. You haven't really explained what your goal is so we can't really advise on the details. But, the point is you have lots of different options for computing other properties based on the original two names. Here's an example with different constructors:

function PersonName(firstName, lastName) {
   this.firstName = firstName;
   this.lastName = lastName;
   this.fullName = firstName + " " + lastName;
}

function PersonID(firstName, lastName) {
   this.firstName = firstName;
   this.lastName = lastName;
   this.herID = firstName.slice(0, 1) + lastName;
}

var people = [new PersonName("John", "Doe"), new PersonID("Jane", "Doe")];

Lots of options.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Keep in mind that these solutions won't update after a property is modified, e.g.: http://jsfiddle.net/suyd54z8/ – pawel Jan 24 '15 at 17:19
  • Main problem with this is that I cannot make a dynamic declaration. It's got to be a static one :/ – batilc Jan 24 '15 at 17:19
  • @batilc - then as the beginning of my answer says, you can't compute values on previously declared properties in a static declaration. That is a limitation of a static declaration. Why does it have to be static? It's Javascript. Dynamic code like I've shown is allowed. The end result is the same, an array of objects with properties. It shouldn't matter how the objects got created. – jfriend00 Jan 24 '15 at 17:22
  • @pawel - if dynamic updating is desired (which was not part of the OP's question), the dynamic property can be a computed property either with a `getter` property or with a method. – jfriend00 Jan 24 '15 at 17:24
  • @jfriend00 I think I'm gonna roll with your answer and see how it goes. I will need to change some code in other files, but it should be managable – batilc Jan 24 '15 at 17:30
  • @jfriend00 yeah I know, I didn't say your solution is wrong, just that there's this caveat to be aware of. – pawel Jan 24 '15 at 17:30