【问题标题】:String object versus literal - modifying the prototype?字符串对象与文字 - 修改原型?
【发布时间】:2010-09-21 00:43:42
【问题描述】:

我想知道为什么向字符串文字的原型添加方法似乎可行,但添加属性却不行?我正在玩与this question 相关的想法,并且有以下代码:

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。

怎么了?

【问题讨论】:

  • 大多数你称之为“字符串文字”的东西,实际上被称为“字符串原语”:文字是一种描述字符串的语法,例如,分配一个字符串 (或数字、布尔值、对象等)到变量;原始值是变量和对象可以包含的非复合值(除了(其他)对象)。
  • 除非它不是......'indexOf' 不是一个函数时调用一个字符串......

标签: javascript


【解决方案1】:

每次尝试调用String 对象的方法时,字符串原语都会转换为瞬态String 对象(必要时,JavaScript 引擎会在内部将字符串原语转换为String 对象)。在这个函数返回之后,String 对象(不显眼地)被转换回一个字符串原语(在后台),并且这个新的原语被返回(并且大部分时间分配给一个变量); 每次调用String 对象的方法时

因此,在每次调用 testString._str_substr 后,_str_index1 与对象一起被丢弃,并在再次调用 _str_substr 时创建一个新对象(带有重置 _str_index1)。

另见MDC

因为 JavaScript 会自动在字符串原语和 String 对象之间进行转换,所以您可以在字符串原语上调用 String 对象的任何方法。 JavaScript 自动将字符串原语转换为临时 String 对象,调用方法,然后丢弃临时 String 对象。

【讨论】:

  • 是的,这就是我想说的:)
【解决方案2】:

发生这种情况是因为对象被创建并在赋值时立即被丢弃,因为它是一个字符串文字。

所以在第一个版本中,创建并保存了一个对象,所以 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);
};

当然,这些只是旨在帮助解释为什么文字与对象的行为不同的建议,而不是现实世界的建议......

【讨论】:

  • 我也没有。 @不,我不明白你的意思。
  • “对象被创建并在赋值时立即被丢弃”听起来像是在 initial 赋值 (var testString = …) 时创建并丢弃了一个对象,而不是调用_str_substr时。
  • 嗯,我在 ECMAScript 规范中寻找它,但找不到它(至少现在不是)。但如果是这种情况,则在进行字符串分配后就无法调用String 对象的方法。每次调用String 对象的方法时都必须转换字符串原语。
  • Marcel:我想我们说的是同一件事...... AFAIK 一个字符串对象是在遇到字符串时临时创建的,然后被丢弃。也许我错了,关键是它从声明的那一刻起就不是一个对象,它是一个原始的;无国籍,除了它的价值。当您调用字符串原语的“方法”时,就像将 String.prototype.x 应用于文字字符串一样。
  • 你说得对(我们说的是同一件事)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-05
  • 2011-08-12
  • 2017-12-15
  • 1970-01-01
  • 1970-01-01
  • 2018-08-04
相关资源
最近更新 更多