FetchJSON

言語JavaScript
公開日2018/07/06
更新日2018/07/06
対応Standard ECMA-262 5.1 Edition / June 2011 以降
進捗コアの実装段階。動作確認はしているがかなりの部分で検証不足。
履歴
  • 2018

    • 07

      • 13

         「概要」を「文書」に変更して構成を整理。Firefox 以外で正常に表示される気がしない……。内容的には不完全なままです。

      • 12

         「概要」の追加。体裁を整えてるだけで不完全。

      • 06

         試験的な公開。ひとつのオブジェクトと、それを利用した汎用関数に別れてますが、これらは統合予定です。

文書
概要

 JSON に準拠するデータからの情報取得を補助する。データは JSON であることが求められるが、プロパティに循環参照および Object, Array 以外のオブジェクトの指定を許容する。そのため、データは、正確には JSON「準拠」とするよりも JSON「的」とするのが相応しい。一方で、入力されたデータから取得される情報は JSON 同様に列挙可能(enumerable)で、for...inで列挙される添字に限られる。例えば prototype を遡らない。また、列挙可能ではあるものの、キーに Symbol を指定した Object のプロパティも参照しない。要素が不連続な配列の未指定部分は補間され、値はundefinedになる。例えばvar a = []; a[2] = 1;[ undefined, undefined, 1 ]となる。これらの仕様、特にキーを Symbol にしたプロパティを対象とするかどうかは実際の使用上の利便性を鑑みて変更する可能性がある。

 現状では、このオブジェクトは空の初期化関数以外何も継承可能なプロパティを持たない。そのためインスタンスを作成する意味はない。

メソッド
init
  • prototype

 初期化関数。現状では何もしない。コンストラクター実行時に呼び出される。

  • Object
  • Array
cloneEnum
  • 0
    • json
      • Object
      • Array

 第一引数 json に指定した JSON 互換のデータから列挙可能なプロパティをディープコピーしたものを返す。FetchJSON 自身のプロパティで、使用する際はインスタンスからではなく FetchJSON から直接呼び出す必要がある点に注意。json は JSON 互換であることが期待されるが、循環参照と Object, Array 以外のオブジェクトの指定が許容される。ただし、それらは再帰もディープコピーもされず、コピーされるのはそれらの参照に限られる。

 このメソッドによって作成されるディープコピーのもっとも特徴的な点として、json 内の参照関係も再現されることが挙げられる。var a = {}, b = {}, c; a.a = a.b = b, c = FetchJSON.cloneEnum(a);とした場合、a.a === a.b; a.a !== c.a;がいずれも true なのは当然として、c.a === c.b;も true を示す。こうしたディープコピー内での参照関係の再現はネスト数に関係なく行われ、循環参照であったとしても、その循環先をコピー元ではなくコピー先の参照に変えた上で循環を再現する。

  • Object
prefetchCloneEnum
  • 0
    • detail
      • Object
  • 1
    • $
      • Object

 メソッド cloneEnum 内で実行する再帰処理から呼び出されるコールバック関数で、それ以外で使用する必要はない。cloneEnum の第一引数に指定された json をディープコピーするための情報を作成する。例えば json 内のすべてのオブジェクトの json 内での参照回数をカウントするなどしている。この情報を用いて json 内のオブジェクトの参照関係をディープコピー内で再現する。

  • Object
  • Array
onCloneEnum
  • 0
    • detail
      • Object
  • 1
    • $
      • Object

 メソッド cloneEnum 内で実行する再帰処理から呼び出されるコールバック関数で、それ以外で使用する必要はない。cloneEnum の第一引数に指定された json のディープコピーを実際に作成する。

  • Variable
recursive
  • 0
    • json
      • Object
      • Array
  • 1
    • nestCallback
      • Function
  • 2
    • cycleCallback
      • Function
  • 3
    • destCallback
      • Function
  • 4
    • upCallback
      • Function
  • 5
    • that
      • Object
  • 6
    • detail
      • Variable

 汎用再帰処理関数。FetchJSON 自身のプロパティで、使用する際はインスタンスからではなく FetchJSON から直接呼び出す必要がある点に注意。第一引数 json に指定されたデータの列挙可能なすべてのプロパティに、ネストされたものも含めてアクセスする。汎用であるため、この関数自体は入力データに対して何も行わない。入力データに対する処理に応じて、引数に指定されたコールバック関数を呼び出し、そのコールバック関数内でデータへの処理を行う。つまり操作処理は任意で実装する必要がある。コールバック関数は第六引数 that に指定されたスコープで、第七引数 detail に指定された任意の値を引数にして実行される。detail の他にこの関数の実行中の情報が参照可能なオブジェクト $ も引数として渡される。データがネストする際は第二引数 nestCallback に指定された Function を実行する。循環参照を検出した時は第三引数 cycleCallback に指定された Function を実行する。Object, Array 以外のオブジェクトを含む値を検出した時は第四引数 destCallback に指定された Function を実行する。ネスト先からネスト元に戻る際は第五引数 upCallback に指定された Function を実行する。いずれも未指定の場合は何も行わない。nestCallback, upCallback はすべてのネストの前後に実行される。つまり json 内のプロパティへのアクセスを開始する前、終了したあとにも実行される。この実行は通常のネスト前後の実行と見かけ上および処理上で区別されることはないが、コールバック関数に引数として渡される $ のプロパティの差異によってコールバック関数内で判別することができる。戻り値は detail だが、その detail は第七引数に渡された値ではなくrecursive 処理内で実行された各コールバック関数の戻り値である。つまり、第七引数に値を渡し、その値を各コールバック関数内で処理し、それをコールバック関数の戻り値とすることで、任意の戻り値を指定することができる。と言っても、すべてのコールバック関数を指定して戻り値を設定する必要はなく、コールバック関数が未指定の場合は、detail の値は保たれる。そのため、例えばすべてのコールバック関数が未指定の場合は、recursive の戻り値は第七引数に指定された値のままとなる。一方で、コールバック関数を指定した時に戻り値を指定しないと、detail の連続性はそこで喪失することになる。

$
概要

 メソッド recursive 内で処理に応じて実行されるコールバック関数に第二引数として渡される Object。第一引数には recursive の第七引数 detail が渡される。detail と $ はすべてのコールバック関数の共有の引数として使用される。そのためコールバック関数内でそれらの値を変更する際は注意が必要である。特に $ 内のプロパティは一部を除き recursive 処理内で実際に使用されるため、あくまで参照に留めるべきである。変更した場合は処理の整合性が取れなくなり、最悪の場合は無限ループになる恐れがある。にもかかわらず、$ が示す情報はコールバック関数内での利用が不可欠で、それらの利用抜きでは意味のある再帰処理を行えない。そうした危険がありながらもそれらのプロパティに対し各種操作の禁止フラグを設定しないのは処理コストを稼ぐ以外に理由が存在しない。

プロパティ
source

 現在ネストされている Object, Array で、現在アクセスしているプロパティの値を示す。例えば現在のネスト対象が [ 0, 1, 2 ] だった場合、destCallback の $.source で示される値は順番に 0, 1, 2 になる。また、一番最初と一番最後に呼び出される nestCallback のこのプロパティの値は recursive の第一引数 json そのものとなる。

sources

 現在ネストされている Object, Array を示す。一番最初と最後に呼び出される nestCallback のこのプロパティの値は null になる。そのため recursive の実行開始、終了を判別する際にこのプロパティを使うことができる。

highers

 現在までにネストされた対象を、ネストされた順番で並べた配列を示す。この配列に現在のネスト対象、つまり sources は含まれない。この配列の length は、そのまま現在のネスト数を表す値として使うことができる。

keys

 現在までにネストされた対象の列挙可能なすべてのプロパティの名前(Array の場合は番号)を並べた配列を、ネストされた順番に並べた配列で示す。highers と同様に現在ネストしている対象のものは含まれない。現在ネストしている対象のプロパティ名、番号は後述するプロパティ k によって示される。

elapse

 現在ネストされているプロパティの名前、番号を、ネスト順に $.keys 内のの位置で示す。例えば json が{ a: 0, b: [ { a: 0 } ] }だったとして、一番深い{ a: 0 }の時に $.keys の値は[ [ 'a', 'b' ], [ 0 ] ]を、$.elapse の値は[ 1, 0 ]を示す。これに対し$.keys[$.elapse[i]]のようにネストされた順番で $.elapse を $.keys の添字にしてアクセスすると、 'b', 0 となり、現在までのネストのプロパティ名、番号が順に得られる。highers, keys と同様に現在のネスト対象のものは含まれない。現在のネスト対象でこのプロパティに相当する値は、プロパティ i によって示される。

k

 現在ネストしている対象の列挙可能なすべてのプロパティ名ないし番号を並べた配列。要素が不連続な Array は、連続していない部分が undefined で補間される。recursive の開始時、終了時は、この値は null になる。

i

 現在ネストしている対象がアクセスしているプロパティの名前ないし番号の前述のプロパティ k 内での位置を示す番号を整数で示す。例えば、destCallback 内で現在の値のプロパティ名を取得したい場合は $.k[$.i] とすることができる。recursive の開始時、終了時は、この値は -1 になる。

context

 recursive がコールバック関数を実行した時の状況を文字列で示す。recursive の開始、終了時およびネストする時は NEST,プロパティの値にアクセスした時(非ネスト時)は DEST、循環参照を検出した時は CYCLE、現在のネストから上位のオブジェクトに戻る時は UP が指定される。この文字列で区別される状況は、それぞれ recursive に引数として渡せるコールバック関数に対応している。このプロパティを使えばそのコールバック関数をひとつの関数に共通化するのが容易になる。

path
  • getter

 現在までのネスト対象の、ネストしたプロパティ名ないし番号を並べた配列を示す。この配列には、現在のネスト対象が、現在アクセスしているプロパティ名ないし番号も含まれる。json が { a: 0, b: [ { a: 0 } ] } で、一番深い { a: 0 } にアクセスされた時にdestCallback 内でこのプロパティを通じて得られる path は [ 'b', 0, 'a' ] となる。このプロパティは getter によって定義されているため、他の多くのプロパティと異なり書き換えが許容される。逆に言えば、このプロパティを参照する度に同じ値の配列が生成されるため、このプロパティの値を編集する際は一度変数に指定して、その変数内の配列に対して編集処理を行うべきである。

isObject

 現在のネスト対象が Object の場合は true、Array の場合は false を示す。

avoid

 コールバック関数内でこのプロパティの値に true 相当の値を指定すると、そのコールバック関数後の recursive 内での既定の処理をスキップする。例えば nestCallback では、nestCallback 実行後のネストが行われない。destCallback および cycleCallback では、現在のネスト対象の次のプロパティへのアクセスをスキップする。upCallback では、ネストを上位に戻すのをスキップし、さらにその上位へネストを戻す。destCallback,cycleCallback, upCallback での動作は未実装で、upCallback については現在は上位に戻す処理そのものをスキップし、実質 recursive を強制終了させる。

done

 コールバック関数内でこのプロパティの値に true 相当の値を指定すると、そのコールバック関数の実行状況を問わず、recursive そのものの実行を強制終了させる。その際も recursive の戻り値は得られる。

内容
fetchj.js
px.js
参考文献