4

.slice()JavaScript のコピーを作成するために、引数のないメソッドを常に使用してきましたArray。これは、私が試したすべてのブラウザーと JavaScript 環境で問題なく動作し.slice(0)ます。

これは単なるスタイルの問題ですが、start引数を完全に省略すると、配列の特別なサブスライスを取得するのではなく、全体のコピーが必要であることがより明確になります。

ただし、MDNMSDNarray.slice()の両方で、最初の引数がrequiredであると述べています。2 番目の引数のみがオプションです。TutorialsPointW3Schoolsなどの他のオンライン ソースも同じことを述べています。(いいえ、私は W3Schools を推奨しているわけではありません! この問題に関して、彼らが MDN と MSDN に同意していることを指摘しているだけです。)

私はこれで幸運だったのでしょうか?array.slice()動作しないブラウザまたはその他の JavaScript 環境はありますか?

4

1 に答える 1

9

これらのオンライン参照はすべて間違っています。

少なくとも、標準に準拠したブラウザーとランタイムについて話しているのであれば.

ECMA-262 標準では、準拠するすべての実装をarray.slice()と同じように扱う必要がありますarray.slice(0)

これが私たちがこれを知る方法です。

まず、セクション 15.4.4.10の「Array.prototype.slice (開始、終了)」を見てください。

このメソッドはstartendsliceの2 つの引数を取り、要素startから要素end まで(または end が の場合は配列の末尾まで)の配列の要素を含む配列を返します。undefined

これは何ですか?endがオプションであるという言及さえありません。開始終了の両方が必要ですか?

はい、そうです。しかし、これが何を意味するのかを理解するには、別の場所に目を向ける必要があります。

セクション 15の「標準の組み込み ECMAScript オブジェクト」には、次のように書かれています (第 4 段落)。

特定の関数の説明で特に指定されていない限り、この節で説明されている関数またはコンストラクターに、関数が要求するように指定されているよりも少ない引数が与えられた場合、関数またはコンストラクターは、十分な追加の引数が与えられた場合とまったく同じように動作します。そのような引数はundefined値です。

これは、他のメソッドの指定方法と一致しています。たとえば、compare 関数の引数 toarray.sort()がオプションであることはわかっていますが、セクション 15.4.4.11 「Array.prototype.sort (comparefn)」では、 comparefn引数がオプションであることについて何も述べていません。これは、 comparefnが存在するかどうかにかかわらず、何をすべきかを説明するだけundefinedです。

これで、array.slice()が と解釈されることがわかりましたarray.slice(undefined,undefined)。次に、セクション 15.4.4.10を続けると、関連するステップが見つかります。

5. relativeStartをToInteger ( start ) とします。

ToIntegerセクション 9.4で説明されており、最初の 2 つの手順が関連しています。

1. numberを入力引数で ToNumber を呼び出した結果とします。
2. number が の場合NaN、 を返し+0ます。

ToNumberセクション 9.3にあり、表の最初のエントリには、引数の型が未定義の場合、結果は であることが示されていますNaN

したがって、欠落している の最初の引数array.slice()は として扱われundefined、その値は ToNumber に渡され、 が返されますNaN。これにより、ToInteger が返され0(または+0、ここで呼び出されます)、それがarray.slice()使用する値です。

したがって、array.slice()と同じarray.slice(0)です。実装がそのように扱わない場合、ECMA-262 標準に準拠していません。

もちろん、それが標準であり、そこには現実世界があります。

の2 番目の引数についてこの同じ分析に従うと.slice()、これらはすべて同じように機能するはずであるという結論に達します (他の同様のバリエーションの中でも)。

array.slice()
array.slice( 0 )
array.slice( undefined )
array.slice( 0, undefined )
array.slice( undefined, undefined )

ただし、@ Pumbaa80 がコメントで指摘しているように、最後の 2 つのバージョンは IE8 (または IE7) では機能しません!

しかし、少なくともarray.slice()私が懸念していた単純なケースは、これらの古いブラウザーで機能し、標準に従うすべてのブラウザーまたはランタイムで引き続き機能するはずです。

于 2013-08-12T06:35:25.857 に答える