자바 스크립트에서 [] .slice.call에 대한 설명은 무엇입니까?


197

DOM NodeList를 일반 배열로 변환하기위한이 깔끔한 지름길을 우연히 발견했지만 작동 방식을 완전히 이해하지 못합니다.

[].slice.call(document.querySelectorAll('a'), 0)

그것은 하늘의 배열로 시작 그래서 [], 다음 slice의 결과를 변환하는 데 사용됩니다 call그래 새로운 배열에?

내가 이해하지 못하는 것은 call입니다. document.querySelectorAll('a')NodeList에서 일반 배열 로 어떻게 변환 합니까?


5
Array.prototype.slice.call(document.querySelectorAll('a'));작성한 코드 덩어리를 작성하는 적절한 방법입니다.
vdegenne

4
BTW는 현대적이고 직관적으로 이해할 수있는 ES6 방법입니다 Array.from. 따라서 예를 들면 다음과 같습니다. Array.from (document.querySelectorAll ( 'a'));
rugk

답변:


158

여기서 일어나는 일은 slice()마치를 NodeList사용 하는 함수처럼 호출한다는 것 call()입니다. 어떤 slice()이 경우에 수행하는 것은 현재 실행중인 개체 (지금은 원래 배열을 통해 다음 반복,를 빈 배열을 만들 것이다 NodeList) 결국 반환이 만든 빈 배열로 객체의 요소를 추가 유지. 여기에 대한 기사가 있습니다.

편집하다:

빈 배열로 시작합니다. [], 호출 결과를 새로운 배열로 변환하기 위해 slice가 사용됩니다.

그건 맞지 않습니다. [].slice함수 객체를 반환합니다. 함수 객체에는 call()의 첫 번째 매개 변수를 할당 하는 함수 를 호출하는 함수 call()가 있습니다 this. 즉, 함수 가 배열이 아닌 매개 변수 (에서 NodeList반환 document.querySelectorAll('a')) 에서 호출되었다고 생각하게합니다 .


59
여기서도 의미 적으로는 말과 동일하지만 Array.prototype.slice.call(...)실제로 []프로토 타입 슬라이스 메소드에 액세스하기 위해 배열 객체 ( )를 인스턴스화합니다 . 그것은 낭비되는 인스턴스입니다. 말하는 Array.prototype.slice.call(...)당신 JS에 여러 문자를 추가 있지만 대신 청소기, 당신 경우있는 거 계산 ...
벤 Zotto

IE 8 이하에서는 Array 객체에서만 작동하므로 NodeLists 를 복제 할 수 없습니다.
Livingston Samuel

5
@quixoto []Array다른 것에 덮어 쓸 수 있기 때문에 더 안정적 입니다. 을 재사용해야하는 경우 Array#slice이를 캐시하는 것이 좋습니다.
Mathias Bynens

2
다른 사람이 IE8에서이 작업을 수행 할 방법을 찾고 있다면이 질문을 확인하십시오. stackoverflow.com/questions/3199588/…
Liam Newmarch

1
실제로이 패턴이 backbone.js 소스 코드에 나타나는 것을 보았습니다 : var array = []; var push = array.push; var slice = array.slice; var splice = array.splice;그는 @MathiasBynens가 언급 한 안전 문제에 대해이 작업을 수행합니까?
owensmartin

125

JavaScript에서 객체의 메서드는 런타임에 다른 객체에 바인딩 될 수 있습니다. 간단히 말해서, 자바 스크립트는 객체가 다른 객체의 메소드를 "빌리도록"허용합니다.

object1 = {
    name: 'Frank',
    greet() {
        alert(`Hello ${this.name}`);
    }
};

object2 = {
    name: 'Andy'
};

// Note that object2 has no greet method,
// but we may "borrow" from object1:

object1.greet.call(object2); // Will show an alert with 'Hello Andy'

callapply이 작업을 수행 할 수 있습니다 함수 객체의 방법 (물론 자바 스크립트는 함수 객체). 따라서 코드에서 NodeList가 배열의 슬라이스 메소드를 빌리고 있다고 말할 수 있습니다. .slice()다른 배열을 결과로 반환하여 사용할 수있는 "변환 된"배열이됩니다.


자바 스크립트 객체의 기능에 대한 🎯 추상 개념 설명. 이제 일명 call기능에 적용 할 수 있습니다 . Array.prototype[].prototype
Sourabh

29

에서 slice함수를 검색합니다 Array. 그런 다음 해당 함수를 호출하지만 결과를 실제 배열 대신 객체 document.querySelectorAll로 사용합니다 this.


19

배열과 유사한 객체를 실제 배열로 변환하는 기술입니다.

이러한 개체 중 일부는 다음과 같습니다.

  • arguments 기능에서
  • NodeList (가져온 후 내용이 변경 될 수 있음을 기억하십시오!
  • jQuery 컬렉션, 일명 jQuery 객체 (일부 문서 : API , type , learn )

예를 들어 객체는 참조로 전달되고 배열은 값으로 전달됩니다.

또한, 첫 번째 인수주의 0, omited 수 있습니다 여기에 철저한 설명 .

그리고 완전성을 위해 jQuery.makeArray ()도 있습니다.


15

어떻게 그 변환 document.querySelectorAll('a')A로부터 NodeList 규칙적인 배열에?

이것은 우리가 가진 코드입니다.

[].slice.call(document.querySelectorAll('a'), 0)

먼저 해체하자

  []    // Array object
.slice // Accessing the function 'slice' present in the prototype of Array
.call // Accessing the function 'call' present in the prototype of function object(slice)
(document.querySelectorAll('a'),0) 
    // 'call' can have arguments like, (thisArg, arg1,arg2...n). 
   // So here we are passing the 'thisArg' as an array like object,
  // that is a 'nodeList'. It will be served as 'this' object inside of slice function.
 // And finally setting 'start' argument of slice as '0' and leaving the 'end' 
// argument as 'undefined'

1 단계 : call기능 실행

  • 내부 call이외는 thisArg, 인수의 나머지는 인수 목록에 추가됩니다.
  • 이제 함수 slice는 (객체에서 온 배열과 같은) this값을 인수 목록과 함께 바인딩하여 호출됩니다 . 즉 , 포함하는 인수thisArgdocument.querySelectorstart0

2 단계 : 2 slice내부에서 호출 된 함수 실행call

  • start변수에 다음 s과 같이 할당 됩니다0
  • 이후 end이다 undefined, this.length에 저장됩니다e
  • 빈 배열은 변수에 저장됩니다 a
  • 위의 설정을 한 후 다음과 같은 반복이 발생합니다.

    while(s < e) {
      a.push(this[s]);
      s++;
    }
    
  • 채워진 배열 a이 결과로 반환됩니다.

추신 시나리오에 대한 이해를 돕기 위해 문맥에 필요한 일부 단계는 호출슬라이스 의 원래 알고리즘에서 무시되었습니다 .


1
단계별 설명이 아주 좋습니다. 대박! 감사합니다 :)
kittu

1
좋은 설명입니다.
NaveenDA

7
[].slice.call(document.querySelectorAll('.slide'));

1. The querySelectorAll() method returns all elements in the document that matches a specified selector(s). 

2. The call() method calls a function with a given this value and arguments provided individually.

3. The slice() method returns the selected elements in an array, as a new array object.

  so this line return the array of [object HTMLDivElement]. Here is the six div with classname "slide" so array length will be 6.

<div class="slideshow">

  <div class="slide">
    first slider1
  </div>
  <div class="slide">
    first slider2
  </div>
  <div class="slide">
    first slider3
  </div>
  <div class="slide">
    first slider4
  </div>
  <div class="slide">
    first slider5
  </div>
  <div class="slide">
    first slider6
  </div>

</div>

<script type="text/javascript">

  var arraylist = [].slice.call(document.querySelectorAll('.slide'));

  alert(arraylist);

</script>

4

ES6에서 : Array.from (element.children) 또는 Array.from ({length : 5})으로 간단히 배열을 만듭니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.