Строковый объект по сравнению с литералом - изменение прототипа?

Мне интересно, почему кажется, что добавление метода к прототипу строкового литерала работает, а добавление свойства - нет? Я играл с идеями относительноэтот вопроси иметь следующий код:

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));
​

Это отлично работает. Однако, если я изменю третью последнюю строку на:

var testString = 'Loremipsumdolorsitamet,consectetur';

... кажется, что хотя метод_str_substr существует и может вызываться на строковом литерале, значение свойства_str_index1 всегда 0.

Что происходит?

 Cris Stringfellow03 нояб. 2012 г., 08:48
За исключением случаев, когда это не так ... 'indexOf' не является функцией при вызове против строки ....
 Marcel Korpel21 сент. 2010 г., 03:23
Наиболее из того, что вы называете «строковым литералом», фактически называется «строковым примитивом»: литералы - это синтаксис для описания строки, например, для присвоения переменной (или числу, логическому, объекту и т. д.) переменной; Примитивные значения являются несоставными значениями, которые могут содержать переменные и объекты (кроме (других) объектов).

Ответы на вопрос(2)

Решение Вопроса

Примитив строки преобразуется в переходный процессString объект каждый раз, когда вы пытаетесь вызвать методString объект (механизм JavaScript внутренне преобразует строковый примитив вString объект при необходимости). После возврата этой функцииString объект (ненавязчиво) преобразуется обратно в строковый примитив (под капотом), и этот новый примитив возвращается (и большую часть времени назначается переменной);каждый раз, когда методString объект вызывается.

Итак, после каждого вызоваtestString._str_substr, _str_index1 выбрасывается вместе с объектом и новым объектом (со сбросом_str_index1) создается когда_str_substr называется снова.

Смотрите такжеMDC:

Поскольку JavaScript автоматически конвертирует между строковыми примитивами и объектами String, вы можете вызвать любой из методов объекта String в строковом примитиве. JavaScript автоматически преобразует строковый примитив во временный объект String, вызывает метод, а затем отбрасывает временный объект String.

 Dagg Nabbit21 сент. 2010 г., 03:03
Да, именно это я и пытался сказать :)

Это происходит потому, что объект создается и сразу выбрасывается при назначении, потому что это строковый литерал.

Таким образом, в первой версии объект создается и сохраняется, поэтому testString - это объект, а не строковый литерал. Во втором случае объект создается и выбрасывается, поэтому все свойства теряются ...

Теперь попробуйте заменить эту строку на это:

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

Интересно, правда? Он по-прежнему возвращает строковый примитив, но это можно исправить ...

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);
};

Конечно, это всего лишь предложения, призванные помочь объяснить, почему литералы действуют не так, как объекты, а не рекомендации реального мира ...

 spender21 сент. 2010 г., 02:48
Я не понимаю
 Marcel Korpel21 сент. 2010 г., 03:09
«Объект создан и сразу же выброшен при назначении» звучит так, как будто объект создан и выброшен наначальная назначение (var testString = …), а не при вызове_str_substr.
 Marcel Korpel21 сент. 2010 г., 03:55
Вы правы (об этом мы говорим об одном и том же).
 sje39721 сент. 2010 г., 02:49
Нет, я тоже. @ нет, я понятия не имею, что ты имеешь в виду.
 Dagg Nabbit21 сент. 2010 г., 03:20
Марсель - этоявляется.
 Dagg Nabbit21 сент. 2010 г., 03:52
Марсель: Я думаю, что мы говорим об одном и том же ... AFAIK Объект String временно создается, когда встречается строка, а затем выбрасывается. Может быть, я ошибаюсь, дело в том, что это не объект с момента его объявления, это примитив; без гражданства за исключением его стоимости. Когда вы вызываете «методы» строкового примитива, это похоже на применение String.prototype.x к литеральной строке.
 Marcel Korpel21 сент. 2010 г., 03:41
Хм, я ищу его в спецификации ECMAScript, но не могу найти его (по крайней мере, не в этот час). Но если бы это было так, методString объект не может быть вызван после назначения строки. Строковый примитив необходимо преобразовывать каждый раз, когда методString объект вызывается.

Ваш ответ на вопрос