Question

I asked in IRC chat yesterday whether it was possible to have an element update with any changes to an object it references, rather than just keep the value it was given upon being declared. For example

Arr1 = [1,2,3]
i1 = Arr1.length-1
last1 = Arr1[i1]

Arr1.push(4)

Checking last1 at the end of this (arbitrary) example shows it has not updated to reflect the newly added value of 4, so objects in JS aren't "live" by default.

I'm a beginner but I'd worked this out from practice already, but was told this was actually the case... I guess my question wasn't understood.

NodeList objects are "live" however, and I'm wondering if there are other types of object in JS that do so, as it would obviously save lines of code spent updating them.

Was it helpful?

Solution

One important distinction here is that i1 does not "reference" anything here. It is simply storing the numeric result of the expression Arr1.length-1 when that line executed. Likewise, last1 may or may not reference the value that was the third element of Arr1 when line 3 executed, but it maintains no reference to Arr1 itself or anything about it.

As in some other programming languages, variables that are assigned to objects are references, so you can do this:

var obj1 = { prop1: "hello", prop2: "goodbye" };
var obj2 = obj1;
obj2.prop1 = "buongiorno";
console.log(obj1.prop1);  // result is "buongiorno"

But this doesn't seem to be quite what you're describing.

It sounds like what you're describing is some sort of reactive programming. JavaScript doesn't really work the way you're imagining, but you could accomplish this using closures:

var Arr1 = [1,2,3];
var i1 = function() { return Arr1.length - 1; };
var last1 = function() { return Arr1[i1()]; };

console.log(i1());    // result is 2
console.log(last1()); // result is 3

Arr1.push(4);

console.log(i1());    // result is 3
console.log(last1()); // result is 4

Note that here, the () parentheses at the end are required to call these functions and get their current value.

One even trickier thing you could do is the following:

function capture(fcn) { 
    return { valueOf: fcn, toString: function() { return fcn().toString(); } };
}

var Arr1 = [1,2,3]
var i1 = capture(function() { return Arr1.length - 1; });
var last1 = capture(function() { return Arr1[i1]; });

console.log(last1 * 5); // result is 15

Arr1.push(4);

console.log(last1 * 5); // result is 20

Note however that this second technique has its limitations. You have to coerce the values into the type that you would expect or call their .valueOf() method in order for them to produce an actual value. If you just used:

console.log(last1);

You would not get any sort of friendly result.

OTHER TIPS

I interpret your question as why are some variables which are copies are updated when you change the original value and others are not.

This is because some types of variables are Reference Types and others are Value Types. Numbers, dates and strings are value types and are copied whenever you assign them to a variable. Objects, Arrays (which are also an Object) are reference types and are not copied, just referenced.

This example is using value types and any change to the first variable will not be copied:

var foo = 1;
var bar = foo; // this is copying the value from the foo variable to bar
foo = 2;
console.log(bar); // 1

compared to the same thing but with a reference to an object:

var foo = {prop:1};
var bar = foo; // this is creating a reference to the foo object
foo.prop = 2;
console.log(bar.prop); // 2
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top