나는 그것이 인수를 실제 배열로 만드는 데 사용된다는 것을 알고 있지만 사용할 때 어떤 일이 발생하는지 이해하지 못한다 Array.prototype.slice.call(arguments)
답변
후드 아래에서 발생하는 .slice()
것은 정상적으로 호출 될 때 this
배열이며 배열을 반복하고 작업을 수행한다는 것입니다.
함수 this
에서 어떻게 .slice()
배열입니까? 당신이 할 때 :
object.method();
…는 object
자동의 값이된다 this
하여 method()
. 따라서 :
[1,2,3].slice()
… [1,2,3]
배열은 this
in 의 값으로 설정됩니다 .slice()
.
그러나 다른 것을 this
가치 로 대체 할 수 있다면 어떨까요? 대체하는 것이 숫자 .length
속성과 숫자 인덱스 인 많은 속성을 갖는 한 작동합니다. 이 유형의 객체를 종종 배열 형 객체 라고 합니다 .
.call()
및 .apply()
방법은 당신이 할 수 수동으로 값을 설정 this
하는 기능에. 우리의 값으로 설정 그래서 경우 this
에를 .slice()
로 배열과 같은 객체 , .slice()
단지 것입니다 가정 이 배열로 일하고, 그 일을 할 것입니다.
이 평범한 물체를 예로 들어 보겠습니다.
var my_object = {
'0': 'zero',
'1': 'one',
'2': 'two',
'3': 'three',
'4': 'four',
length: 5
};
이것은 분명히 배열이 아니지만 this
값을 로 설정할 수 있으면 제대로 작동 .slice()
하기 .slice()
에 충분히 배열처럼 보이기 때문에 작동합니다.
var sliced = Array.prototype.slice.call( my_object, 3 );
예 : http://jsfiddle.net/wSvkv/
콘솔에서 볼 수 있듯이 결과는 다음과 같습니다.
['three','four'];
따라서 arguments
객체를 this
값으로 설정하면 이런 일이 발생합니다 .slice()
. 속성과 많은 숫자 인덱스 arguments
가 있기 때문에 실제 배열에서 작업하는 것처럼 작업을 수행합니다..length
.slice()
답변
arguments
객체는 실제로 배열의 인스턴스가 아닌, 및 배열 방법을 가지고 있지 않습니다. 따라서 arguments.slice(...)
arguments 객체에 slice 메서드가 없으므로 작동하지 않습니다.
배열에는이 방법이 있으며 arguments
객체는 배열과 매우 유사하기 때문에 두 개가 호환됩니다. 즉, arguments 객체와 함께 배열 메서드를 사용할 수 있습니다. 그리고 배열 메소드는 배열을 염두에두고 작성되었으므로 다른 인수 오브젝트가 아닌 배열을 리턴합니다.
왜 사용 Array.prototype
합니까? 는 Array
우리가 (의 새로운 배열을 생성하는 객체입니다 new Array()
), 그리고이 새로운 배열은 조각처럼, 방법 및 속성을 전달됩니다. 이러한 메소드는 [Class].prototype
객체에 저장됩니다 . 따라서 효율성 향상을 위해 (new Array()).slice.call()
또는로 슬라이스 방법에 액세스하는 대신 [].slice.call()
프로토 타입에서 바로 가져옵니다. 따라서 새로운 배열을 초기화 할 필요가 없습니다.
그러나 왜 우리는 처음에 이것을해야합니까? 글쎄, 당신이 말했듯이, 그것은 arguments 객체를 Array 인스턴스로 변환합니다. 그러나 슬라이스를 사용하는 이유는 무엇보다 “핵”입니다. slice 메소드는 배열의 슬라이스를 가져 와서 그 슬라이스를 새로운 배열로 반환합니다. arguments 객체를 인수로 컨텍스트에 전달하지 않고 전달하면 slice 메서드는 전달 된 “배열”(이 경우 arguments 객체)의 전체 청크를 가져 와서 새 배열로 반환합니다.
답변
일반적으로 전화
var b = a.slice();
배열 a
을에 복사합니다 b
. 그러나 우리는 할 수 없습니다
var a = arguments.slice();
arguments
실제 배열이 아니며 slice
메소드 가 없기 때문 입니다 . Array.prototype.slice
는 IS slice
배열 기능과 call
함께 기능을 실행 this
에 집합 arguments
.
답변
먼저 JavaScript에서 함수 호출이 작동하는 방식 을 읽어야 합니다 . 혼자서도 귀하의 질문에 대답하기에 충분하다고 생각합니다. 그러나 여기에 무슨 일이 일어나고 있는지 요약되어 있습니다.
Array.prototype.slice
추출물 방법 에서 의 프로토 타입 . 그러나 메서드 (함수가 아님) 이므로 컨텍스트 (호출 객체 ) 가 필요하므로 직접 호출하면 작동 하지 않습니다 . 그렇지 않으면 throw 됩니다.slice
Array
this
Uncaught TypeError: Array.prototype.slice called on null or undefined
이 call()
메소드를 사용하면 메소드의 컨텍스트를 지정할 수 있으며 기본적으로이 두 호출을 동일하게 만듭니다.
someObject.slice(1, 2);
slice.call(someObject, 1, 2);
전자의 경우를 제외하고는 slice
메소드가 someObject
프로토 타입 체인 에 있어야 Array
하지만, 후자는 컨텍스트 ( someObject
)를 메소드에 수동으로 전달할 수 있습니다.
또한 후자는 다음과 같이 짧습니다.
var slice = Array.prototype.slice;
slice.call(someObject, 1, 2);
다음과 같습니다.
Array.prototype.slice.call(someObject, 1, 2);
답변
// We can apply `slice` from `Array.prototype`:
Array.prototype.slice.call([]); //-> []
// Since `slice` is available on an array's prototype chain,
'slice' in []; //-> true
[].slice === Array.prototype.slice; //-> true
// … we can just invoke it directly:
[].slice(); //-> []
// `arguments` has no `slice` method
'slice' in arguments; //-> false
// … but we can apply it the same way:
Array.prototype.slice.call(arguments); //-> […]
// In fact, though `slice` belongs to `Array.prototype`,
// it can operate on any array-like object:
Array.prototype.slice.call({0: 1, length: 1}); //-> [1]
답변
Array.prototype.slice.call (arguments)는 인수를 배열로 변환하는 구식 방법입니다.
ECMAScript 2015에서는 Array.from 또는 스프레드 연산자를 사용할 수 있습니다.
let args = Array.from(arguments);
let args = [...arguments];
답변
그 때문에, 같은 MDN 노트
arguments 객체는 배열이 아닙니다. 배열과 비슷하지만 길이를 제외하고 배열 속성이 없습니다. 예를 들어, pop 메소드가 없습니다. 그러나 실제 배열로 변환 할 수 있습니다.
여기에서 우리는 호출하는 slice
기본 객체 Array
가 아닌 자사에 구현 하고 그게 왜 추가.prototype
var args = Array.prototype.slice.call(arguments);