20

Is there any way I can be less verbose in JavaScript by pointing a local variable by to an objects property?

For instance in PHP I can do this:

$obj->subobject->property = 'Foo';
$property =& $obj->subobject->property;
$property =  'Bar';
echo $obj->subobject->property;
// output 'Bar'

It's not a very good example but you get the idea.

I want to copy this behaviour in Javascript. I'm quite often having to go quite deep into objects and it's getting quite annoying having to do:

if (please.stop.making.me[somevar].type.so.much.length) {
    please.stop.making.me[somevar].type.so.much[newSubObjectKey] = anObject;
}

// perform more operations on the object down here

It would be a lot easier to read and a lot easier to type:

var subObj = is.much.easier.to.type.once;
if (subObj.length) {
     subObj[newSubObjectKey] = anObject;
}

// now that's much better

I know I should really know this already, but I'm just advancing to "advanced novice" in JavaScript.

informatik01
  • 16,038
  • 10
  • 74
  • 104
rich97
  • 2,809
  • 2
  • 28
  • 34
  • 2
    [javascript variable reference/alias](http://stackoverflow.com/questions/1686990/javascript-variable-reference-alias) – Igoris Azanovas Jul 18 '11 at 12:07
  • Then how is it that changing arguments [0] changes variable 'a', a primitive type in the following example? `var a = 55;
    A(a);
    function A (a) { arguments [0] = 44; console.log (a); // outputs 44, not 55 }`
    – tgoneil Jun 30 '14 at 19:02
  • Sorry for the clumsy editing. pls ignore '
    '
    – tgoneil Jun 30 '14 at 19:20

4 Answers4

29

In JavaScript, everything is passed by value, but the variable's type will determine whether it's a reference passed by value or not;

  • Objects are references
  • Primitives (numbers, strings etc) are passed by value.

In simple terms, if you pass a variable to a function that's an array, modifying it in the function will affect the parent.

However, passing it a value in the array will not. Naturally, there's absolutely nothing stopping you wrapping a primitive in an object to ensure it works like a "pointer".

informatik01
  • 16,038
  • 10
  • 74
  • 104
Olipro
  • 3,489
  • 19
  • 25
  • It seems as though you're correct http://jsfiddle.net/ZSvyt I liked your explanation too! – rich97 Jul 18 '11 at 12:38
  • What do you mean by 'wrapping a primitive in an object'? I tried `const {thing1, thing2}= obj ` where `obj= {thing1: "someValue", thing2: "someOtherValue"}` and expected `thing1` and `thing2` to change along with `obj`'s attributes but they don't. – mqbaka mqbaka Sep 30 '21 at 13:56
7

You can assign a new variable to reference any depth in a chain of property keys, so long as the entry referred to isn't a primitive type.

This works because a bare object variable is actually a reference to that variable, so your new (shorter) variable can point to the same place.

However primitive number and string values are passed by value, so you can't create new references to those.

Alnitak
  • 334,560
  • 70
  • 407
  • 495
  • 1
    I believe this is the most clear direct answer to the question. You can simply assign it to a variable, in the example given, and it will work like the asker wants, provided it's not a primitive (it's probably not). – Frug Apr 20 '14 at 02:06
4

It would be a lot easier to read and a lot easier to type:

var subObj = is.much.easier.to.type.once;
if (subObj.length) {
     subObj[newSubObjectKey] = anObject;
}

Have you even tried the above? Because it works.

As for the actual question. You cannot have references or pointers to values. Everything is passed by value in javascript (not reference).

Edit: I forgot to mention some values are references. You still can't get a pointer to those reference values.

Raynos
  • 166,823
  • 56
  • 351
  • 396
  • 2
    Your last sentence is not completely correct. Objects/Arrays/Functions are passed by reference. – pimvdb Jul 18 '11 at 12:09
  • 7
    _Everything is passed by value in javascript_ - true, except that the value of an object variable is actually a reference to it. When you pass that reference the called function can modify the original object. – Alnitak Jul 18 '11 at 12:11
  • 4
    @Raynos it's not pedantry, it's a very important detail. – Alnitak Jul 18 '11 at 12:16
0

coffeeScript code

# result method
Object::r = (v) ->
    s=@
    st='global.'+v+'={'+'s'+'}'
    re=(eval st)
    str='global.'+v+'=re["s"]'
    eval(str)
    @


[1..10].r('a').
    map( (v) -> 'lorem_ipsum_'+v.toString() ).r('ar').
    join("__").r('s').
    split("__").reverse().r('arr')

console.log("\n")
console.log(a); console.log("\n")
console.log(ar); console.log("\n")
console.log(s); console.log("\n")
console.log(arr); console.log("\n")

screenShot