Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

String object versus literal - modifying the prototype?

Tags:

javascript

I'm wondering why it seems that adding a method to the prototype of a string literal seems to work, but adding a property does not? I was playing with ideas in relation to this question, and have the following code:

String.prototype._str_index1 = 0;
String.prototype._str_reset = function() {
    this._str_index1 = 0;
};
String.prototype._str_substr = function(len) {
  var ret = this.substr(this._str_index1, len);
  this._str_index1 = this._str_index1 + len;
  return ret;
};

var testString = new String('Loremipsumdolorsitamet,consectetur');
log(testString._str_substr(5));
log(testString._str_substr(4));
​

This works fine. If however I change the third-last line to:

var testString = 'Loremipsumdolorsitamet,consectetur';

...it seems that although the method _str_substr exists and is callable on the string literal, the value of the property _str_index1 is always 0.

What's up?

like image 327
sje397 Avatar asked Sep 21 '10 00:09

sje397


People also ask

What is the difference between a String variable and a String Literal?

The main difference between String Literal and String Object is that String Literal is a String created using double quotes while String Object is a String created using the new() operator. String is a set of characters. Generally, it is necessary to perform String operations in most applications.

Can we modify String Literal in Java?

The Java String is immutable which means it cannot be changed. Whenever we change any string, a new instance is created. For mutable strings, you can use StringBuffer and StringBuilder classes.

What is a literal object?

Object literals An object literal is a list of zero or more pairs of property names and associated values of an object, enclosed in curly braces ( {} ).

What is String prototype in JavaScript?

Definition and Usage The prototype is a property available with all JavaScript objects. The prototype property allows you to add new properties and methods to strings.


2 Answers

The string primitive is converted to a transient String object every time you try to invoke a method of the String object (the JavaScript engine internally converts a string primitive to a String object when necessary). After this function returns, the String object is (unobtrusively) converted back to a string primitive (under the hood) and this new primitive is returned (and most of the time assigned to a variable); every time a method of the String object is invoked.

So, after each invocation of testString._str_substr, _str_index1 is thrown away with the object and a new object (with a reset _str_index1) is created when _str_substr is called again.

See also MDC:

Because JavaScript automatically converts between string primitives and String objects, you can call any of the methods of the String object on a string primitive. JavaScript automatically converts the string primitive to a temporary String object, calls the method, then discards the temporary String object.

like image 56
Marcel Korpel Avatar answered Oct 20 '22 02:10

Marcel Korpel


This happens because the object is created and immediately thrown away when the assignment is made, because it's a string literal.

So with the first version, an object is created and kept, so testString is an object, not a string literal. In the second case, an object is created and thrown away, so all properties get lost...

Now try replacing that line with this:

var testString = 'Loremipsumdolorsitamet,consectetur'._str_substr();

Interesting, right? It still returns a string primitive, but that could be fixed...

String.prototype._str_substr = function(len) {
  var ret = this.substr(this._str_index1, len);
  this._str_index1 = this._str_index1 + len;
  return new String(ret);
};

Of course these are just suggestions designed to help explain why literals act differently than objects, not real-world recommendations...

like image 2
Dagg Nabbit Avatar answered Oct 20 '22 02:10

Dagg Nabbit