Js

JSでの[] .slice.callの理解



Understanding Slice



元の: https://www.cnblogs.com/wuvkcyan/p/9446800.html

まず、[]。slice.call()とArray.prototype.slice.call()の違いは何ですか?



[].slice === Array.prototype.slice true

[]配列を作成するには、[]。sliceの場合、自然にプロトタイプチェーンに移動します

[].__proto__.slice === Array.prototype.slice true

Array.prototype.sliceは、オーバーライドできる定義済みのメソッドです。



[] .silceは定義されたメソッドを使用しています

  1. 自身のさまざまな属性(プロトタイプと[]の違いのため)
Object.getOwnPropertyNames(Array.prototype) (37) ['length', 'constructor', 'concat', 'pop', 'push', 'shift', 'unshift', 'slice', 'splice', 'includes', 'indexOf', 'keys', 'entries', 'forEach', 'filter', 'map', 'every', 'some', 'reduce', 'reduceRight', 'toString', 'toLocaleString', 'join', 'reverse', 'sort', 'lastIndexOf', 'copyWithin', 'find', 'findIndex', 'fill', 'remove', 'removeFirstIf', 'removeIf', 'repeat', 'last', 'lastDef', 'clone'] Object.getOwnPropertyNames([]) ['length']

したがって、本質的に[]とArray.prototypeの間に本質的な違いはありませんが、呼び出しには違いがありますが、専門家によるテストによれば、[]は少し高速です。

MDNでのスライスの解釈は次のとおりです。
スライス()メソッドは、新しい配列オブジェクトへの浅いコピーのために、最初から最後まで選択された配列の一部(終了を含まない)を返し、元のオブジェクトは変更されません。



var animals = ['ant', 'bison', 'camel', 'duck', 'elephant'] console.log(animals.slice(2)) // expected output: Array ['camel', 'duck', 'elephant'] console.log(animals.slice(2, 4)) // expected output: Array ['camel', 'duck'] console.log(animals.slice(1, 5)) // expected output: Array ['bison', 'camel', 'duck', 'elephant']

パラメータには2つのスライス(begin、end)があります

ベギン :

パラメータがない場合は、0から始めます
それがインデックスから来るときです(最初のビットは0です)
パラメータが負の場合、元の配列の最後のいくつかの要素から抽出することを意味し、slice(-2)は、元の配列の最後から2番目の要素を最後の要素に抽出することを意味します。要素(最後の要素を含む)
終わり :

パラメータがない場合、デフォルトは配列の最後になります
配列の長さよりも大きい場合は、配列の最後を取ります
スライス(1,4)4番目の要素のすべての要素(インデックス1、2、3の要素)まで元の配列の2番目の要素を抽出します
引数が負の場合は、元の配列の最後の要素が抽出を終了することを意味します。

var a = [1,2,3,4,5,6,7,8] a.slice(3,-2) (3) [4, 5, 6]

戻り値

抽出された要素を含む新しい配列

スライスは元の配列を変更せず、元の配列の要素を直接コピーする新しい配列を返すだけです。

要素がオブジェクト参照(実際のオブジェクトではない)の場合、スライスはオブジェクト参照を新しい配列にコピーします。両方のオブジェクト参照は同じオブジェクトを参照しています。参照されるオブジェクトが変更されると、新しい元の配列のこの要素も変更されます。

文字列、数値、ブール値(String、Number、またはBooleanオブジェクトではない)の場合、sliceはそれらの値を新しい配列にコピーします。他の配列でこれらの文字列または数値またはブール値を変更しても、他の配列には影響しません。

2つの配列のいずれかに新しい要素を追加しても、もう一方は影響を受けません。

上記は、MDNのスライスの専門的な説明です。

スライスこのメソッドは、引数を受け入れない場合にこれ自体を返します。

引数は関数内の変数であり、値は関数パラメーターのリストであり、クラス配列オブジェクトであり、長さ属性ですが、配列ではなく、slice()メソッドがありません。つまり、arguments.slice()にはありません。作業。

ここで、これの呼び出しを変更できます。これに対する引数の呼び出しを使用すると、スライスが発生しますか?

スライスは、長さ属性を持つオブジェクトを取得し、そのオブジェクトを配列に認識します

function list() { return Array.prototype.slice.call(arguments) } console.log(list(1, 2, 3))

誰かが尋ねるでしょう、なぜ引数の呼び出しを配列に変更できるのですか?内部で何が起こりますか?

私たちはslice()を実装してそれを理解することができます。

ミシリツェ()

Array.prototype.Myslice = function (begin,end){ var start = begin || 0 / / Determine the existence of begin when there is no existence to 0 here can be strengthened var len = this / / Get this.length here to get the object that the call comes in start = (start >= 0) ? start : Math.max(0, len + start) / / Determine whether the parameter is greater than 1, the value of the begin in the case of a negative number end = (typeof end == 'number') ? Math.min(end, len) : len / / Determine whether end is greater than the length of this.length if(end<0){ end = end + len / / Determine the situation of negative values } var result = new Array() for (let i = 0 i < end.length i++) { result.push(this[i]) } return result } function list() { return Array.prototype.Myslice.call(arguments) } console.log(list(1, 2, 3))

ここを見ると、Array.prototype.slice.callがオブジェクトを配列に変える理由がわかります~~~

最後に、JavaScriptsclieのソースコードを貼り付けます

Array.prototype.slice = function(begin, end) { end = typeof end !== 'undefined' ? end : this.length if (Object.prototype.toString.call(this) === '[object Array]') { return _slice.call(this, begin, end) } var i, cloned = [], size, len = this.length var start = begin || 0 start = start >= 0 ? start : Math.max(0, len + start) var upTo = typeof end == 'number' ? Math.min(end, len) : len if (end < 0) { upTo = len + end } size = upTo - start if (size > 0) { cloned = new Array(size) if (this.charAt) { for (i = 0 i < size i++) { cloned[i] = this.charAt(start + i) } } else { for (i = 0 i < size i++) { cloned[i] = this[start + i] } } } return cloned } function list() { return Array.prototype.slice.call(arguments) } console.log(list(1, 2, 3))

記事は個人的な要約です。エラーがある場合は、