4

I've experimented with JavaScript and noticed this strange thing:

var s = "hello world!";
s.x = 5;
console.log(s.x); //undefined

Every type of variable in JavaScript is inherited from object. So it should be possible to add new attributes to every object.

Did I misunderstand something wrong?

Van Coding
  • 24,244
  • 24
  • 88
  • 132

6 Answers6

10

A string in JavaScript isn't an instance of String. If you do new String('my string') then it will be. Otherwise it's a primitive, which is converted to a String object on the fly when you call methods on it. If you want to get the value of the string, you need to call toString(), as shown below:

var s = new String("hello world!");
s.x = 5;
console.log(s.x); //5
console.log(s); //[object Object]
console.log(s.toString()); //hello world!
Skilldrick
  • 69,215
  • 34
  • 177
  • 229
  • Thanks! I never noticed that there is a difference between "hello" and new String("hello"); I logged "hello".__proto__ and got Object. So it was clear for me... – Van Coding Apr 04 '11 at 13:27
1

String objects are objects and can be expanded, but string literals are not string objects and can not be expanded.

Example:

var s = 'asdf';
s.x = 42;
alert(s.x); // shows "undefined"

s = new String('asdf');
s.x = 1337;
alert(s.x); // shows "1337"
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
0

Skilldrick’s answer explains why it doesn’t work and therefore answers your question.

As a side note, it is possible to do this:

var s = {
  toString: function() { return "hello world!"; }
};
s.x = 5;
console.log(s.x); // 5
console.log('result: ' + s); // "result: hello world!";
console.log(String(s)); // "hello world!";
Mathias Bynens
  • 144,855
  • 52
  • 216
  • 248
0

Your s is a string literal, not a string object. String literals are handled differently:

The reason you can't add properties or methods to a string literal is that when you try to access a literal's property or method, the Javascript interpreter temporarily copies the value of the string into a new object and then use that object's properties or methods. This means a String literal can only access a string's default properties or methods and those that have been added as prototypes.

James Sumners
  • 14,485
  • 10
  • 59
  • 77
0

Primitives MDC docs are immutable.

primitive, primitive value
A data that is not an object and does not have any methods.
JavaScript has 5 primitive datatypes: string, number, boolean, null, undefined.
With the exception of null and undefined, all primitives values have object equivalents which wrap around the primitive values, e.g. a String object wraps around a string primitive.
All primitives are immutable.

Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
0

Try to do this:

var s = "hello world!";
s.prototype.x = 5;
console.log(s.x);
DStereo
  • 251
  • 3
  • 4
  • This would add the x property to ALL string object and is not what I wanted to do ;) – Van Coding Apr 04 '11 at 13:32
  • Gives "TypeError: Result of expression 's.prototype' [undefined] is not an object." Anyway, even if s was a string object, objects don't inherit from their own prototype but that of their constructor, which is referenced by the internal [[prototype]] property. – RobG Apr 04 '11 at 13:39