4

In the following example, why doesn’t the value property of the input with the ID test update to "second"?

document.getElementById("test").addEventListener("click", () => {
  let test = document.getElementById("test").value;
  
  test = "second";
  console.log(test); // Logs "second", but input value is not updated.
});
<label>Click on this test input: <input type="text" id="test" value="first"></label>
Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
sapiensgladio
  • 219
  • 1
  • 3
  • 13
  • I get it, but can someone explain WHY you can set a reference to the object [document.getElementByID('test')]but not to the object's value [document.getElementByID('test').value]? – sapiensgladio Jun 09 '11 at 01:24
  • http://docstore.mik.ua/orelly/webprog/jscript/ch11_02.htm – Jared Farrish Jun 09 '11 at 01:35
  • "The basic rule in JavaScript is this: primitive types are manipulated by value, and reference types, as the name suggests, are manipulated by reference." – Jared Farrish Jun 09 '11 at 01:43
  • In the end, `document.getElementById().value` is a property. When you set a variable to what it returns, that's a copy of the value found in that property. Javascript does not give you the option of accessing a memory pointer/reference of that value. – Jared Farrish Jun 09 '11 at 01:50
  • Related: [If a variable is defined in terms of another, can it reflect changes in the binding of the other?](/q/42637782/4642212). – Sebastian Simon Oct 20 '22 at 09:11

12 Answers12

6

Because Javascript assigned x as a value and not a reference to the original object.

For example, you could instead:

function setText(x) {
    document.getElementById('test').value = x;
}

getText = function() {      
    return document.getElementById('test').value;
}

And the value you set with setText() will be reflected by getText(), since getText() will also use the reference object's value, and not a copy of the value.

EDIT

As Bryan points out, this would be a copy by reference with a global scope:

var test = document.getElementById('test');

function setText(x) {
    test.value = x;
}

getText = function() {      
    return test.value;
}

http://jsfiddle.net/nLj2A/

The original test variable stores a reference to the element, not a value associated with an attribute of the element.

Jared Farrish
  • 48,585
  • 17
  • 95
  • 104
  • Aye, and you can store a reference here with `var test = document.getElementById("test")` and then doing something like `test.value = "second"`. – brymck Jun 06 '11 at 21:07
  • @Bryan - That's true, since you would be copying a reference to the `#test` DOM element. For purposes of the example and clarity, I chose to illustrate that directly. :) – Jared Farrish Jun 06 '11 at 21:08
3

You are copying the value to a variable. Changing the variable won't change the original, because the variable just contains a copy.

If you store the reference of the element in the variable, you can use that to set the value:

var test = document.getElementById('test');
test.value = "second";
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
1

You're assigning the element's value to a variable and then changing the variable. This is not reflected back in the element's value. You need to change the element's value instead.

document.getElementById('test').value = "second";
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
0

Because you're setting the value of test to be the string document.getElementById('test').value.

You aren't linking the two together.

If you are looking to do that, you can use a function:

function test(x) {
  document.getElementById('test').value = x;
}

test('foo');

In Python, you can do this. In JavaScript, I don't think so.

Blender
  • 289,723
  • 53
  • 439
  • 496
0

because

document.getElementById('test').value

is a getter where as

document.getElementById('test').value = "second"

is a setter

locrizak
  • 12,192
  • 12
  • 60
  • 80
0
test = document.getElementById('test').value;

...only gives you a copy of the value at that instant. When you modify test, you need to put that back into input field you'd like to change:

var test_input = document.getElementById('test');
test_input.value = "second";
kafuchau
  • 5,573
  • 7
  • 33
  • 38
0

Setting the local variable test to "second" will do nothing. I assume you want getText to update the DOM. Try this:

 getText = function() { document.GetElementById('test').value("second"); }
Richard Schneider
  • 34,944
  • 9
  • 57
  • 73
0

Point to element instead of value: http://jsbin.com/axufi4/edit

Drew
  • 4,683
  • 4
  • 35
  • 50
0

Although javascript ultimately treats everything as an object, I believe only arrays and objects are passed by reference. Strings, ints and floats are passed by value.

Text inputs will always give you a string (even if you restrict input to numbers)

tomfumb
  • 3,669
  • 3
  • 34
  • 50
  • 2
    Not even objects and arrays are passed *by* reference, they are passed *as* references. You can change the contents of the object, but you can't replace the object with another. – Guffa Jun 06 '11 at 21:08
  • Everything in JavaScript is pass-by-value. – Pointy Jun 06 '11 at 21:14
0
<script type="text/javascript">
    getText = function() {      
        var test = document.getElementById('test').value;
        test = "second";
        //note: if you insert "alert(test)" it returns "second"
        document.getElementById('test').value = test;
    }
</script>
mrtsherman
  • 39,342
  • 23
  • 87
  • 111
0

You need to do this:

document.getElementById('test').value = "second";

or

var el = dcument.getElementById('test');
el.value = "second";

As for why, I believe it has to do with something about Javascript being a "pass by reference" or "pass by value" language, on which subject there was a very interesting discussion here on SO. (I'm not sure on this point, correct me if I'm wrong).

Community
  • 1
  • 1
Félix Saparelli
  • 8,424
  • 6
  • 52
  • 67
0

because it's a string and is passed as value, not as reference. so the content of value is copied to test

Alessandro Pezzato
  • 8,603
  • 5
  • 45
  • 63