3

I'm not even sure exactly what I'm asking here. I just know it isn't what I expected.

I have a page script (see below) that grabs a reference to an element by its ID, then calls a few functions on it. Each function logs the element (or its textContent) to the console, modifies the text contents, then calls the next function. What confuses me is how those changes are logged.

If I log element.textContent, I get the behavior I expected: Each log prints the string as left by the previous function.

If I log the element itself, I get a different behavior*: Each log outputs the element in its final state, not its state when the log was called.

This leads me to think that the element is passed by reference, resulting in all the references being updated together as the script continues, while the element's text contents are logged by value.

If this is true, how do I know which behavior to expect? Are all DOM references passed by reference, while strings (primitives) by value? As I understand it, JavaScript passes objects by reference and primitives by value. Is that what’s happening here?

*The output from JS Bin is far more verbose that Chrome gives—but it does describe the elements as of type object, however. The full code I was using is (using element.textContent, not element) below.

<html>
<body>
<p id="paragraph">First paragraph</p>
<script>
  (function () {
    'use strict'

    var one = function () {
      console.log(example.textContent)
      example.textContent = example.textContent.replace('paragraph', 'call')
      two()
    }
    var two = function () {
      console.log(example.textContent)
      example.textContent = example.textContent.replace('First', 'Second')
      three()
    }
    var three = function () {
      console.log(example.textContent)
      example.textContent = example.textContent.replace('Second', 'Third')
      console.log(example.textContent)
    }

    var example = document.getElementById('paragraph')
    console.log(example.textContent)
    one()
  })()
</script>
</body>
</html>
ele
  • 6,021
  • 5
  • 25
  • 35
  • 3
    Any object is passed by reference (to be precise: a reference is passed by value). Any string is passed by value. – zerkms Sep 15 '14 at 03:15
  • Right - objects as values are **always** references. – Pointy Sep 15 '14 at 03:15
  • 1
    This is not a problem with passing values. Rather it is a problem of console.log - console.log, when passed a reference, doesn't take a snapshot of the object the reference refers to. Therefore the value of what you log is always the value at the time you inspect it in the console, not at the time you call console.log. – slebetman Sep 15 '14 at 03:18
  • @zerkms An object is passed by reference but the reference is passed by value? I'm afraid I don't follow. – ele Sep 15 '14 at 03:19
  • Traditionally this console.log issue has always been closed as a duplicate of one of the other questions of the console.log issue but I'm too lazy to find them today. Someone close this. – slebetman Sep 15 '14 at 03:19
  • @ele when a variable (or a parameter) "is" an object, what it *really* is is a reference to the object. That's the value that's passed when you pass an object to a function: the **reference**. It kind-of helps if you don't think about it too much; in JavaScript that's the only way to deal with objects anyway. – Pointy Sep 15 '14 at 03:20
  • @ele: It's exactly like C. C has no pass by reference at all it ALWAYS passes by value. So how do you pass pointers then? Well the object is passed as a pointer but the pointer is passed by value. – slebetman Sep 15 '14 at 03:21

1 Answers1

0

If this is true, how do I know which behavior to expect?

Read the documentation for the relevant API. For example, the HTML5 specification for the DIV element includes a link to the interface HTMLDivElement API that tells you what various methods and properties return.

Unfortunately, HTML5 doesn't include all relevant information, so you also have to check other specifications such as the W3C DOM Core for textContent.

You can also look around the Mozilla Developer Network (MDN) for various web APIs. Probably the simplest way is to just call the method or access the property and see what it returns using typeof.

RobG
  • 142,382
  • 31
  • 172
  • 209