0

次の構造のオブジェクトを拡張しようとしています(CoffeescriptのJQueryを使用):

objectThatIsAList = {
  'List Item'      : 
    callback       :=>
      return "Some value"
  'Another item'   :
    callback       :=>
      return "Another value"
  'The final item' :
    callback       :=>
      no
}

このオブジェクトは、大規模な coffeescript ベースのフレームワークでドロップダウン メニューの (動的) モデルとして使用されます。

私はそれを拡張しています

objectThatIsAList = $.extend {}, objectThatIsAList,  {
  'New Item' :
    callback :=>
      return "New stuff"
}

これにより、次のようなオブジェクトが得られます (意図した結果を示すためにコメントが追加されました)

objectThatIsAList = {
  'List Item'      : 
    callback       :=>
      return "Some value"
  'Another item'   :
    callback       :=>
      return "Another value"

  # this should be last
  'The final item' :
    callback       :=>
      no

  # this should not be last
  'New Item'       :
    callback       :=>
      return "New stuff"
}

明らかに、オブジェクトは正しく拡張されますが、プロパティの順序はリストを作成する目的に関連しています。拡張オブジェクトの 3 番目のプロパティではなく、4 番目のプロパティとして を使用したいと考えています。'Final Item'

しかし、私の調査では、このメソッドのインデックス作成のサポートは示されませんでした$.extend。誰かがそのような機能を正常に実装したり、特定の位置で別のオブジェクトにオブジェクトのプロパティを「挿入」する方法のヒントを持っていますか?

または、の後にその最終アイテムを再配置する賢い方法はあり$.extendますか?

必ずしも Coffee である必要はありません。JS や Pseudocode でも大いに役立ちます。

編集:

これは、レガシー コードを拡張して配列を取得し、それらをオブジェクトに変換する、私が思いついたソリューションです (フレームワーク全体で広く使用されており、元のコードを変更すると多くの作業コードが壊れる場合があります)。

# this comparison yields a data object that is passed to a method rendering a menu
if o.menu instanceof Array
  menuArrayToObj = {}
  for menuObject in o.menu
    for menuObjectProperty,menuObjectValue of menuObject
      menuArrayToObj[menuObjectProperty]=menuObjectValue if menuObjectProperty? and menuObjectValue?
  o.menu = menuArrayToObj
else o.menu 

これを配置すると、オブジェクトまたは配列のいずれかを供給することができます。後者はスプライスで簡単に挿入できます。

4

3 に答える 3

2

Javascriptオブジェクトは、定義上、順序付けされていません。

注文を維持したい場合は、Array代わりに必要です。

この良い例は、jQueryUIダイアログオブジェクトです。Objectオプションの場合と同じようにを使用することは可能buttonsですが、個々のボタンを特定の順序にする必要がある場合は、オブジェクトの配列を指定する必要があります。

このモデルを使用すると、オブジェクトは次のようになります。

arrayThatIsAList = [
  { title: 'List Item', callback: ... },
  { title: 'Another Item', callback: ... },
  { title: 'New Item', callback: ... },
  { title: 'The final item', callback: ... }
];
于 2012-10-16T23:02:01.733 に答える
1

$.extend()2 つ以上のオブジェクトを 1 つにマージするために使用されます。順序を管理しません

データを並べ替える場合は、オブジェクトの配列を使用し (インデックスを使用してデータを操作できます)、オブジェクトのタイトルを比較するカスタムの並べ替え関数を使用する必要があります。

yourArray.sort(sortfunction);

function sortfunction(yourObjectA, yourObjectB){
    //Compare yourObjectA and yourObjectB, and return -1, 0, or 1
}
于 2012-10-16T23:25:24.313 に答える
0

への呼び出しの最初の引数として最初に行くプロパティを持つオブジェクトを配置します$.extend

objectThatIsAList = $.extend { 
  'New Item' : 
    callback :=> 
      return "New stuff" 
}, objectThatIsAList

"いいえ!" 「ECMAScript の仕様では、明示的にプロパティの列挙順序が定義されていません!」と叫びます。

そうですね。有効なポイント。 ただし、最新の ECMAScript 実装はすべて、定義された順序でプロパティを列挙します。デファクトスタンダードとなります。ここで試してみてください: jsfiddle.net/TqfNE。定義順以外の順序でプロパティを一覧表示するブラウザーを誰も見つけることができないと思います。

したがって、仕様ごとに保証されているわけではありませんが、すべての実用的な目的のために、一貫して機能します。

ただし、整数をプロパティ名として使用し始めると、ブラウザー間で一貫性のない結果が得られることに注意してください。

于 2012-10-16T23:10:45.443 に答える