27

私は John Resig の優れた高度な JavaScript チュートリアルを読んでいますが、次の呼び出しの違いを完全には理解していません: (「引数」は組み込みの JavaScript 単語であり、厳密には配列ではないことに注意してください。単純に arguments.slice を呼び出す代わりに)

>>> arguments  
[3, 1, 2, 3]  
>>> Array.slice.call( arguments )  
3,1,2,3 0=3 1=1 2=2 3=3  
>>> Array.slice.call( arguments, 1 )  
[]
>>> Array().slice.call( arguments )  
3,1,2,3 0=3 1=1 2=2 3=3  
>>> Array().slice.call( arguments, 1 )  
1,2,3 0=1 1=2 2=3  

基本的に、私の誤解は Array.slice と Array().slice の違いに要約されます。これら2つの違いは正確には何ですか?また、Array.slice.callが期待どおりに動作しないのはなぜですか? (これは、引数リストの最初の要素を除くすべてを返します)。

4

6 に答える 6

39

そうではありません。

String.substring.call("foo", 1) と String().substring.call("foo", 2) を呼び出すとどうなるかを見てください。

>>> String.substring.call("foo", 1)
"1"

>>> String().substring.call("foo", 1)
"oo"

Array.slice は、Array プロトタイプにアタッチされたスライス関数も、インスタンス化された Array インスタンス (Array() や [] など) にアタッチされたスライス関数も正しく参照していません。

Array.slice が null ではないという事実は、オブジェクト (/function/constructor) 自体の不適切な実装です。 IE で同等のコードを実行してみると、Array.slice が null であるというエラーが表示されます

これが、Array.slice が正しく動作しない理由です (String.substring も同様です)。

証明 (以下は、上記の substring() と同様に、slice() の定義に基づいて決して期待してはならないものです):

>>> Array.slice.call([1,2], [3,4])
3,4

ここで、インスタンス化されたオブジェクトまたはArray プロトタイプのいずれかで slice() を適切に呼び出すと、期待どおりの結果が得られます。

>>> Array.prototype.slice.call([4,5], 1)
[5]
>>> Array().slice.call([4,5], 1)
[5]

もっと証拠...

>>> Array.prototype.slice == Array().slice
true
>>> Array.slice == Array().slice
false
于 2008-09-23T14:22:51.487 に答える
6

Array は単なる関数ですが、特別な関数 (配列の初期化に使用) ではあります。Array.slice は、Array プロトタイプの slice() 関数への参照です。配列オブジェクトでのみ呼び出すことができ、コンストラクター (つまり配列) 自体では呼び出すことができません。ただし、Array() は空の配列を返すため、Array は特別に動作するようです。これは、非組み込みのコンストラクター関数では機能しないようです (new を使用する必要があります)。そう

Array().slice.call

と同じです

[].slice.call
于 2008-09-23T13:39:18.330 に答える
1

コンテキスト パラメーターが提供されていないため、提供されている例では、slice.call() への呼び出しはどのように機能していますか? スライスは独自の call メソッドを実装しているので、JavaScript の call メソッドをオーバーライドしていますか? call メソッドと apply メソッドは、呼び出しに適用するコンテキスト (this) オブジェクトを指定するオブジェクトを最初のパラメーターとして取ります。

于 2009-11-28T20:22:08.053 に答える
0

Arrayが型で、Array()がコンストラクター関数だと思います。

FireBugをいじる:

>>> Array === Array()
false

>>> Array.constructor
Function()

>>> Array().constructor
Array()
于 2008-09-23T13:51:37.723 に答える
-1

良い、

http://www.devguru.com/Technologies/ecmascript/quickref/slice.htmlを見る

Array().slice は配列クラスの関数 (コンストラクタ) です. データメンバとしては使えません. 「()」を使用したくない場合は、配列で呼び出す必要があります。つまり、arguments.slice(1)

于 2008-09-23T13:42:46.560 に答える
-1

私の推測では、Array はプロトタイプですが、Array() は実際の配列オブジェクトです。JavaScript の解釈によっては、組み込みオブジェクト型のプロトタイプ メソッドを直接呼び出しても機能する場合と機能しない場合があります。インスタンス化されたオブジェクトでそれを呼び出すことが機能するというだけで、仕様が機能しなければならないと言っているとは思いません。

于 2008-09-23T13:43:31.673 に答える