1

I ran into an unexpected behavior in both Chrome and the Node.js runtime today.

var x = 'I am a string';
console.log(x[0]); //String 'I'
console.log(x[0][0]); //String 'I'
console.log(x[0][0][0]); //String 'I'

I realize that accessing string indexes through brackets is not preferred and not universally supported, so my interest here is purely one of curiosity. What this implies to me is that strings are being built out of strings - ie, the character 'I' is itself a string with the character 'I' at index 0, which is itself a string... it's turtles all the way down.

Or this seems to imply to me that webkit just builds a new string object to return back to me every time I use the [] notation on an existing string. Both of those conclusions feel really weird to me.

Are either of them correct? What's going on under the hood when I call x[0]?

Edit: Related to below answer: Are strings object?

Community
  • 1
  • 1
danShumway
  • 450
  • 4
  • 15
  • Pretty much everywhere except for really old versions of IE allows the use of `[ ]` to access string parts. – Pointy Mar 29 '15 at 00:07
  • 1
    you can also do `"hello".valueOf().valueOf().valueOf()` too, no big whoop... – dandavis Mar 29 '15 at 00:08
  • I guess what's surprising about it to me is that javascript doesn't just treat the bracket notation like a method that's going to return a processed value, it treats it like an actual property. `'hello'.hasOwnProperty(0)` will actually return true. It makes sense from an implementation perspective, I just really wasn't expecting it. – danShumway Mar 29 '15 at 00:51

1 Answers1

1

There is no "character" data type in JavaScript. All that a portion of a string can be is a string.

Note that a string is not an object. A string is a primitive value.

Accessing portions of strings with the [] involves first an implicit wrapping of the string value in a String instance (resulting in an object instance). The [] operator is applied to that object, you get the result (a string), and then the wrapper is thrown away. (Since the wrapper object is ephemeral the runtime is allowed to sneak around actually implementing the semantics in exactly that way.)

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String - the string isn't always primitive... – nicael Mar 28 '15 at 23:59
  • @nicael a string (lower-case "s") is **always** primitive. The language semantics are such that when a string (lower-case "s") is used in a context that demands an object, a String (upper-case "s") instance is implicitly wrapped around the string (lower-case "s") value. – Pointy Mar 29 '15 at 00:02
  • I assume that this is also what's going on behind the scenes when accessing String.prototype (again, not that I'm implying it's good practice to do so). The string (lower-case 's') is wrapped, grabs it's prototype stuff, and then unwraps itself after the fact? – danShumway Mar 29 '15 at 00:03
  • @danShumway yes - the wrapper String instance has the original string value as its internal value, and the wrapper is a fully-functional instance with access to all the prototype methods. – Pointy Mar 29 '15 at 00:04