範囲は値の間隔を表します。値の型は「互換性」がある必要があります。つまり、ある値から次の値にステップ実行できる succ メソッド (その後継メソッド) を実装する必要があります。
ObjectRange オブジェクトは、基本的に連続した数値または文字列を実装します。メソッドは 1 つだけ含まれます。 、数値または文字列が ObjectRange 内にあるかどうかを判断するために含まれます。また、ObjectRange オブジェクトには Enumerable メソッドも混在しているため、ObjectRange オブジェクトで Enumerable オブジェクトのメソッドを直接呼び出すことができます。
//ObjectRange を作成する便利なメソッド
function $ R(start, end, exclusive) {
return new ObjectRange(start, end, exclusive)
}
//ObjectRange オブジェクトを作成し、Enumerable
var を継承します。 ObjectRange = Class.create(Enumerable, (function() {
//初期化メソッド。exclusive が true の場合、終了値は含まれません。デフォルトは未定義であり、false と同等です。
functionInitialize(start) , end, exclusive) {
this.start = start;
this.exclusive = exclusive;
// の _each メソッドをオーバーライドします。 ObjectRange オブジェクトをトラバースする場合は列挙可能です。このメソッドを使用する必要があります。
function _each(iterator) {
var value = this.start;
while (this.include(value)) {
iterator(value) );
value = value.succ();
}
}
//値または文字列が ObjectRange オブジェクトに含まれるかどうかを判断します
function include(value) {
if (値 < this.start)
return false;
if (this.exclusive)
戻り値 <= this.end;
}
return {
initialize: 初期化,
_each: _each,
include: include
})());
見てみましょう。例を挙げて詳細を説明しましょう:
コードをコピーします
$A($R('ax', 'ba'))
// -> ['ax', 'ay', 'az', 'a{', 'a|', 'a}', 'a~'...] で始まる巨大な配列
$A($R('a', 'e')) と値を返す方法について話しましょう。まずは$Aメソッドについて見ていきましょう。$Aメソッドについては以前の記事「プロトタイプ学習 - ツール関数の学習($Aメソッド)」で詳しく説明していますので、ご存じない方はご参照ください。 $A メソッドには次の文があります: if ('toArray' in Object(iterable)) return iterable.toArray(); ObjectRange が Enumerable のメソッドと混在していることがわかります。これは、toArray メソッドが間接的に実装されていることを意味します。 Enumerable の toArray メソッドを見てみましょう:
コードをコピーします
コードは次のとおりです:
関数 toArray() {
return this.map();
}
//======> 🎜>//戻るときに、map メソッドがcollect メソッドにマップされることに気付きました。
return {
//...
collect:collect,
map:collect,
/ / ...
}
//======>collect()
//この場合、このメソッドは実際には配列を返すのと同じです。渡し 受信パラメータはすべて未定義です。ここには this.each メソッドがあります。引き続き
functioncollect(iterator, context) {
iterator = iterator ||
this を見てください。 each( function(value,index) {
results.push(iterator.call(context, value,index));
});
結果を返す
}
// ======> this.each()
//ついに this._each を見て、ObjectRange で _each メソッドがオーバーライドされる理由が分かりました。
function each(iterator, context) {
varindex = 0;
try {
this._each(function(value) {
iterator.call(context,値、インデックス );
});
} catch (e) {
if (e != $break)
これを返します。 >
//======> this._each()
//this._each() を詳しく説明します
//重要なのは succ() メソッドです。メソッドは _each で次の値を生成するために使用されます。
//この succ() はどこですか?このメソッドは Number.prototype および String.prototype で定義されています。
function _each(iterator) {
var value = this.start;
while (this.include(value)) {
iterator( value) );
value = value.succ();
}
}
//以下の 2 つのメソッドについては説明しません。
//======> String.prototype.succ()
function succ() {
return this.slice(0, this.length - 1)
String.fromCharCode(this.charCodeAt(this.length - 1) 1);
}
//======> Number.prototype.succ()
function succ() {
return this 1;
}
//要約すると、Date タイプなど、他のタイプの ObjectRange オブジェクトを定義したい場合は、次のようになります。連続オブジェクトを生成するには、自分で succ() メソッドを実装する必要があります
上記のプロセスは明らかですが、一部の関数は詳細に説明されていません。これらのオブジェクトについて言及する場合、内部の関数について説明します。詳細に。インクルードの例をいくつか見てみましょう:
コードをコピーします
$R(1, 10).include(10) // -> true
$R(1, 10, true).include(10)
// -> ; false