2012-03-16 7 views
5

ES5は、numbermethods~Objectを追加しました。これは、JavaScriptの意味的整合性を損なうようです。ES5のオブジェクトメソッドがObject.prototypeに追加されなかったのはなぜですか?

たとえば、この拡張の前には、JavaScript APIは常にオブジェクトにあります。

var arrayLength = [].length; 
var firstPosInString = "foo".indexOf("o"); 

...ここで、新しいオブジェクトメソッドは次のようになります。

var obj = { }; 
Object.defineProperty(obj, { 
    value: 'a', 
    writable: false 
}); 

...以下のときは、はるかにconformativeただろう:

var obj = { }; 
obj.defineProperty({ 
    value: 'a', 
    writable: false 
}); 

誰もこれが理由として私の好奇心を冷やすことができますか?これが壊れるコードスニペットはありますか?標準化委員会がなぜこのアプローチを選んだのかについての公開討議はありますか?

答えて

5

これはAllen Wirfs-Brock自身の編集者であり、TC39のメンバーであるES5の編集者である"Proposed ECMAScript 3.1 Static Object Functions: Use Cases and Rationale" document(pdf)で非常にうまく説明されています。

私はそれをすべて読むことをお勧めします。かなり短く、簡単に消化でき、これらのES5追加の背後にある思考プロセスを素早く垣間見ることができます。 提案APIが選択された前選択肢のAPI設計の数がを考慮された

:関連セクション(強調鉱山)を引用するが、

。代替案を検討する過程で、我々は が代替案を検討するときに適用した一連の非公式ガイドラインを作成した。これらのガイドラインは以下のとおりです。

  • きれいにメタおよびアプリケーション層を分離。
  • APIの表面積(メソッドの数と引数の複雑さ)を最小限に抑えるようにしてください。
  • 命名とパラメータ設計のユーザビリティに焦点を当てます。
  • デザインの基本要素を繰り返し適用してみます。
  • 可能であれば、プログラマーまたは実装で、APIの使用を静的に最適化できるようにします。

[...]

ここ 選択したデザインにつながると考えられた選択肢の一部です。

明らかに最初のアイデア、すでに 既存の標準的な方法Object.prototype.propertyIsEnumerableの例以下、 他の属性と並列のためのObject.prototypeに追加「propertyIs ...」クエリメソッドを追加 にしました属性変更メソッドのセット。

[...]

我々は好きではなかったし、それが上記APIの設計に ガイドライン反するように見えたこと について多くのことがありました。このアプローチを検討したよう:

    は、
  • は、メタおよびアプリケーションレイヤーを分離するのではなく、マージします。 Object.prototype上のメソッドとして、メソッドは、プログラム内のすべてのアプリケーションオブジェクトの公開 インターフェイスの一部になります。したがって、ライブラリデザイナーだけでなく、すべての開発者が理解できるようにするには、 が必要です。

[...]

+0

興味深い...これが' Object.create'とどのように並んでいるか知っていますか?これらの決定がなされた後、あるいはそれ以前に、Crockfordはそれを 'Object.create'として提案しましたか? –

+0

良い質問です。私は考えていない:)私は、これらのAPIが議論されたほぼ同時に、Crockfordが 'Object.beget'を' Object.create'に改名したと思う。 FWIW、docは次のように述べています:_オプションの第2引数を持たないObject.createは、広く普及しているbeget関数と基本的に同じ操作です。我々は(おそらく驚くことではないが)この機能の有用性に同意したが、 "beget"という言葉はおそらく多くの非母国語の英語話者に混乱していると感じていた.' – kangax

+3

CrockfordはES5デザインに直接携わっていて、その後のデザイン・ディスカッションでは、「作成」が好ましい名前として登場しました。 ESデザインの決定を反映させるために、彼は彼の本の中で "beget"の名前を変更しました。 –

1

JavaScript APIは常にオブジェクト自体のオペラントを中心に回転します。

これは正しくありません。例えば。 JSONMathには常に独自のメソッドがありました。 Object.prototypeを拡張することは悪いことである理由に関するウェブ上の多数の記事があります

var x = 0; 
x.cos(); // 1.0 
({"a":[0,1],"p":{"x":3,"y":4}}).toJSON(); 

:誰もそのようなこともしません。はい、彼らは約クライアントコードだが、かもしれないが、これはいくつかの点でもビルド方法には悪いです。

+1

私はMath' 'についてのあなたのポイントを取る...しかし* *クライアントとして' Object.prototype'の延長の間や言語などの違いは、それ自体が完全に異なっています; *言語*による拡張は 'for(in)'には表示されません。*クライアント*拡張はhttp://jsfiddle.net/mDfCe/1/ – Isaac

+0

となります。私が間違っている。 – kirilloid

+0

...これらのプロパティ( '.constructor'、' .hasOwnProperty'など)は、 "enumerable"属性をfalseに設定してネイティブに定義されているためです。 ES5では、 'for 'ループ(' Object.defineProperty'と 'Object.create'の第二引数)に現れない独自のプロパティを作成することもできます – Krinkle

関連する問題