글을 쓰기 전에
JS에서는 Array.prototype.slice.call(arguments,0) 작성 방법을 자주 볼 수 있습니다. 물론 배열과 유사한 객체를 실제 배열로 변환하는 이 방법의 역할을 누구나 이해할 수 있습니다. . 이 방법에 대해 제가 이해한 바를 말씀드리겠습니다.
여기에는 Slice() 메소드와 call() 메소드가 포함되어 있으므로 먼저 이 두 메소드에 대해 간략히 살펴보겠습니다.
slice() 메서드
배열과 문자열 모두 이 슬라이스 방법을 사용합니다. 이 방법의 기능은 데이터 조각을 가로채는 것입니다. 두 개의 매개변수를 받습니다. 첫 번째 매개변수는 차단할 위치 인덱스입니다. 두 번째 매개변수는 선택사항이며 차단할 끝 위치를 나타내지만 끝 위치는 포함되지 않습니다. 배열에서 이 메서드의 반환 값은 가로채는 요소를 포함하는 배열입니다. 문자열에서 이 메서드의 반환 값은 가로채는 문자열을 포함하는 문자열입니다.
이 메서드는 음수 값을 전달할 수도 있습니다. 매개변수가 음수인 경우 매개변수와 배열 또는 문자열의 길이를 더한 양수가 실제 매개변수로 사용됩니다.
은 다음과 같습니다.
[1,2,3,4,5,6].slice(2,4); [1,2,3,4,5,6].slice(-4,-2);
반환값은 모두 [3,4]로 배열입니다.
'everything'.slice(2,4); 'everything'.slice(-4,-2);
반환값은 각각 'er'와 'hi'로 문자열입니다.
파라미터를 전달하면 시작 위치부터 끝 위치까지의 모든 요소가 출력됩니다. 더 이상 예시가 없습니다.
문자열에 대한 기타 유사한 방법
문자열에는 슬라이스() 유형의 두 가지 다른 메서드가 있습니다.
substring() 및 substr() 메서드.
그 중 substring() 메소드는 시작 위치부터 끝 위치까지 문자열을 반환한다는 의미입니다. substr()은 두 개의 매개변수를 받습니다. 첫 번째 매개변수는 시작 위치를 나타내고, 두 번째 매개변수는 문자열 수를 나타냅니다. 처음 두 가지 방법은 약간 다릅니다.
메서드에 전달된 매개변수가 음수인 경우 이 세 가지 메서드는 약간 다릅니다.
메서드에 전달된 매개변수가 음수인 경우:
slice()는 위에서 언급한 대로 문자열 길이에 음수를 추가하여 해당 양수 값을 얻습니다.
substring() 메서드의 매개변수는 모두 0으로 설정됩니다.
substr() 메소드의 첫 번째 매개변수는 음수에 문자열 길이를 더한 양수 값이고, 두 번째 매개변수는 0으로 설정됩니다.
call() 및 apply() 메소드
call()과 apply() 메소드는 주로 함수의 범위를 확장하는데 사용됩니다.
call() 및 apply() 메소드는 두 개의 매개변수를 받습니다.
apply(): 첫 번째 매개변수는 범위이고, 두 번째 매개변수는 매개변수 배열입니다. 두 번째 매개변수는 배열 인스턴스 또는 인수 객체일 수 있습니다.
call() 메서드도 두 개의 매개변수를 받지만 매개변수를 전달하는 방법이 apply()와 다릅니다. 전달된 함수의 매개변수를 하나씩 작성해야 합니다.
여기서는 이게 핵심이 아니기 때문에 자세한 내용은 다루지 않겠습니다.
Array.prototype.slice.call(arguments,0)
Array.prototype.slice.call(arguments,0)에서 Array.prototype.slice는 Array의 프로토타입 메서드를 호출합니다. 실제 배열의 경우에는 Slice() 메서드가 있지만 인수나 self 같은 경우에는 - 정의 일부 배열 유사 객체에는 길이와 같은 여러 속성이 있지만 Slice() 메서드가 없으므로 이러한 배열 유사 객체의 경우 프로토타입 메서드를 사용하여 Slice() 메서드를 사용해야 합니다. 이는 Array.prototype.slice입니다(맞춤화 중인 경우 배열류 객체에서 Slice() 메서드를 맞춤화하므로 직접 호출할 수 있습니다).
따라서 Array.prototype.slice.call(arguments,0)의 의미는 다음과 같이 이해할 수 있습니다. 인수 클래스 배열의 경우 Array.prototype.slice 프로토타입 메소드를 호출하고 call() 메소드를 사용하여 범위를 In 인수로 제한합니다. 여기서 Array.prototype은 인수로 이해될 수 있으며 매개변수 0은 슬라이스() 메서드의 첫 번째 매개변수로 시작 위치 인덱스입니다. 이러한 방식으로 인수 클래스 배열이 실제 배열로 변환됩니다.
물론 순회를 사용하여 인수를 배열로 변환할 수도 있으므로 코드는 자연스럽게 더 직접적이게 됩니다.
우리는 Array.prototype.slice.call(arguments)이 IE의 노드 컬렉션을 제외하고 길이 속성을 가진 객체를 배열로 변환할 수 있다는 것을 알고 있습니다. (IE의 DOM 객체는 com 객체인 js의 형태로 구현되기 때문입니다. 개체 및 COM 개체는 변환할 수 없습니다.)
예:
var a={length:2,0:'first',1:'second'}; Array.prototype.slice.call(a);// ["first", "second"] var a={length:2}; Array.prototype.slice.call(a);// [undefined, undefined]
아마도 js를 막 배우기 시작한 사람들은 이 문장이 왜 그런 기능을 수행할 수 있는지 잘 이해하지 못할 수도 있습니다. 예를 들어, 나는 그런 사람이므로 살펴보겠습니다.
먼저 슬라이스에는 두 가지 용도가 있습니다. 하나는 String.slice이고 다른 하나는 Array.slice입니다. 첫 번째는 문자열을 반환하고, 두 번째는 배열을 반환합니다.
Array.prototype.slice.call(arguments)은 인수를 배열로 변환할 수 있으며 인수.toArray().slice()입니다. 이 시점에서는 Array.prototype.slice.call(arguments)이라고 말하면 됩니다. ) 프로세스는 전달된 첫 번째 매개변수를 배열로 변환한 다음 Slice?
다음 예시와 같이 call의 사용법을 다시 살펴보겠습니다
var a = function(){ console.log(this); // 'littledu' console.log(typeof this); // Object console.log(this instanceof String); // true } a.call('littledu');
可以看出,call了后,就把当前函数推入所传参数的作用域中去了,不知道这样说对不对,但反正this就指向了所传进去的对象就肯定的了。
到这里,基本就差不多了,我们可以大胆猜一下slice的内部实现,如下
Array.prototype.slice = function(start,end){ var result = new Array(); start = start || 0; end = end || this.length; //this指向调用的对象,当用了call后,能够改变this的指向,也就是指向传进来的对象,这是关键 for(var i = start; i < end; i++){ result.push(this[i]); } return result; }
大概就是这样吧,理解就行,不深究。
最后,附个转成数组的通用函数
var toArray = function(s){ try{ return Array.prototype.slice.call(s); } catch(e){ var arr = []; for(var i = 0,len = s.length; i < len; i++){ //arr.push(s[i]); arr[i] = s[i]; //据说这样比push快 } return arr; } }