ECMA-262 第三版について
第二回目です。
本連載中には,
仕様書としてはわかりにくい部類に入るかな,
また,
では,
String. interpret() と String. specialChar
0198: Object.extend(String, {
0199: interpret: function(value) {
0200: return value == null ? '' : String(value);
0201: },
0202: specialChar: {
0203: '\b': '\\b',
0204: '\t': '\\t',
0205: '\n': '\\n',
0206: '\f': '\\f',
0207: '\r': '\\r',
0208: '\\': '\\\\'
0209: }
0210: });
0211:
別の箇所で使うために,
ここではprototypeプロパティではなくStringオブジェクト直下に直接追加しているので,
199行目のString.
これにより,
例:
result += String.interpret(replacement(match));
specialCharには特殊文字列と,
String.
String オブジェクトへの拡張
String.
0212: Object.extend(String.prototype, {
0213: gsub: function(pattern, replacement) {
0214: var result = '', source = this, match;
0215: replacement = arguments.callee.prepareReplacement(replacement);
0216:
0217: while (source.length > 0) {
0218: if (match = source.match(pattern)) {
0219: result += source.slice(0, match.index);
0220: result += String.interpret(replacement(match));
0221: source = source.slice(match.index + match[0].length);
0222: } else {
0223: result += source, source = '';
0224: }
0225: }
0226: return result;
0227: },
0228:
まずは213行目からの gsub()メソッドです。基本的にはpatternにマッチする文字列を見つけたら,
215行目でreplacementを関数オブジェクトにしている所が多少わかりにくいかもしれません。
ここで,
- 単純な置換後の文字列
- RegExp.
exec()の返す配列を引数として受け取り, 受け取り置換後の文字列を返すFunctionオブジェクト - Prototypeライブラリが提供するTemplateクラスのオブジェクト
のどれが渡されたとしても,
……という挙動を意図しているのだと思われますが,
例えば以下のようになります。
var s = "ABC";
var output = s.gsub('ABC', 'Template では #{...} と書きます。');
alert(output); # 'Template では と書きます。' が出力される
- 公式 API String.
gsub - 公式 API Template
- ECMA-262 第三版 - 15.
10. 6.2 RegExp. prototype. exec(string)
0229: sub: function(pattern, replacement, count) {
0230: replacement = this.gsub.prepareReplacement(replacement);
0231: count = count === undefined ? 1 : count;
0232:
0233: return this.gsub(pattern, function(match) {
0234: if (--count < 0) return match[0];
0235: return replacement(match);
0236: });
0237: },
0238:
String.
233行目ではgsub()のreplacement引数にFuncitonオブジェクトを渡す方法を用いて,
0239: scan: function(pattern, iterator) {
0240: this.gsub(pattern, iterator);
0241: return this;
0242: },
0243:
0244: truncate: function(length, truncation) {
0245: length = length || 30;
0246: truncation = truncation === undefined ? '...' : truncation;
0247: return this.length > length ?
0248: this.slice(0, length - truncation.length) + truncation : this;
0249: },
0250:
scan()はgsub()を呼び出しているだけですが,
truncate()では,
Stringオブジェクトでは内部がUnicodeなので,