Why can’t I add properties to a string object in javascript?

There are 8 language types in JavaScript:

  • 7 primitive types: Undefined, Null, Boolean, Number, BigInt, String, and Symbol
  • 1 non-primitive type: Object

Values of the primitive types are called primitive values and they cannot have properties.
Values of the Object non-primitive type are called objects an they can have properties.

When you try to assign a property named 'bar' to a variable foo, like so:

foo.bar="abc";

then the result will depend on the type of the value of foo:

(a) if the value of foo is of the type Undefined or Null, then an error will be thrown,

(b) if the value of foo is of the type Object, then a named property 'bar' will be defined on the object foo (if necessary), and its value will be set to 'abc',

(c) if the value of foo is of any other type, then a TypeError will be thrown in strict mode: “can’t assign to property "bar" on foo: not an object”. In loose mode, the above assignment operation will be a no op. In either case, the variable foo will not be changed in any way.

So, as you can see, assigning properties to variables only makes sense if those variables are objects. If that is not the case, then the assignment will either do nothing at all, or even throw an error.


In your case, the variable test contains a value of the type String, so this:

test.test = "test inner";

does nothing at all.


However, since ES5 introduced accessor properties, there is an exception to what I’ve said above. Accessor properties allow us to define functions which are invoked whenever the property is either retrieved or set.

For instance:

var str="";
str.prop;

Here str is a variable holding a String value. Therefore, accessing a property of that variable should be a no-op (str.prop merely returns undefined). This is true with one exception: if String.prototype contains a accessor property 'prop' with a defined getter, then that getter will be invoked.

So, if this is defined:

Object.defineProperty( String.prototype, 'prop', {
    get: function () {
        // this function is the getter
    }
}); 

then this

str.prop;

will invoke that getter function. This also works in strict mode.

Live demo: http://jsfiddle.net/fmNgu/

However, I don’t think that adding accessor properties to the built-in prototypes would be a good practice.

Leave a Comment