When you use a string primitive value as if it were an object, JavaScript implicitly creates a String instance from it. It's as if you wrote
console.log(new String(s).getThis().toString());
Primitive values are not objects. However, all the primitive types have built-in Object wrapper types, and those wrapper types are where the various methods (like .charAt()
, .trim()
, .slice()
, etc) are located.
edit — @Bergi points out in a comment that in "strict" mode, the runtime still locates methods from the String and Object prototypes as if a String instance were being created, but the methods are invoked such that this
is a reference to the original primitive value.