Javascript .filter () 메서드의 콜백 함수에 추가 매개 변수를 어떻게 전달합니까?


104

배열의 각 문자열을 주어진 문자열과 비교하고 싶습니다. 내 현재 구현은 다음과 같습니다.

function startsWith(element) {
    return element.indexOf(wordToCompare) === 0;
}
addressBook.filter(startsWith);

이 간단한 함수는 작동하지만 현재 wordToCompare 가 전역 변수로 설정되고 있기 때문에 가능 하지만 물론 이것을 피하고 매개 변수로 전달하고 싶습니다. 내 문제는 기본 매개 변수가 전달되는 방법을 실제로 이해하지 못하기 때문에 startsWith () 를 정의하는 방법을 잘 모르기 때문에 하나의 추가 매개 변수를 허용한다는 것입니다. 나는 내가 생각할 수있는 모든 다른 방법을 시도했지만 그들 중 어느 것도 작동하지 않습니다.

'내장'콜백 함수에 전달 된 매개 변수가 어떻게 작동하는지 설명 할 수 있다면 (죄송합니다.이 용어에 대한 더 나은 용어를 모르겠습니다.)

답변:


152

확인 startsWith에 대해 비교하고 말씀을 받아 들일 함수 반환 후 필터 / 콜백 함수로 사용됩니다 :

function startsWith(wordToCompare) {
    return function(element) {
        return element.indexOf(wordToCompare) === 0;
    }
}

addressBook.filter(startsWith(wordToCompare));

또 다른 옵션은 Function.prototype.bind [MDN] (ECMAScript 5를 지원하는 브라우저에서만 사용 가능, 이전 브라우저의 경우 shim 링크를 따라 가십시오)을 사용하고 첫 번째 인수를 "수정"하는 것입니다.

function startsWith(wordToCompare, element) {
    return element.indexOf(wordToCompare) === 0;
}

addressBook.filter(startsWith.bind(this, wordToCompare));

나는 그것이 취하는 기본 매개 변수가 어떻게 전달되는지 정말로 이해하지 못합니다.

그것에 대해 특별한 것은 없습니다. 어떤 시점 filter에서 콜백을 호출하고 배열의 현재 요소를 전달합니다. 따라서 다른 함수를 호출하는 함수입니다.이 경우에는 인수로 전달하는 콜백입니다.

다음은 유사한 기능의 예입니다.

function filter(array, callback) {
    var result = [];
    for(var i = 0, l = array.length; i < l; i++) {
        if(callback(array[i])) {  // here callback is called with the current element
            result.push(array[i]);
        }
    }
    return result;
}

1
그래. 이제 이해 했어. 매개 변수를 콜백 함수에 직접 전달하려고했습니다. 정말 JavaScript 작업이 필요합니다. 감사합니다 Felix, 귀하의 답변은 매우 유용합니다
agente_secreto 2011-10-13

추가 인수를 전달하는 것은 어떻습니까? 나는 인수의 배열을 전달하려고 시도했지만 실패한 것 같습니다
geotheory dec

@geotheory : 그들에 대해? 다른 함수와 같이 여러 인수를 전달합니다.
Felix Kling 2014

filter () 체이닝과 함께 함수 이름 뒤에 bind (this)는 함수 내부에서 .this를 사용하는 데 도움이되었습니다. 감사.
Sagar Khatri

108

필터의 두 번째 매개 변수는 이를 콜백 내부에 설정 합니다 .

arr.filter(callback[, thisArg])

따라서 다음과 같이 할 수 있습니다.

function startsWith(element) {
    return element.indexOf(this) === 0;
}
addressBook.filter(startsWith, wordToCompare);

7
이것이 최선의 답변이라는 것을 알았습니다.
Jeaf Gilbert

이제 새 배열이 wordToCompare 객체에 할당됩니다. 나중에 wordToCompare 개체를 사용하여 새 배열에 액세스하려면 어떻게해야합니까?
Badhon 자이나교

최고의 답변입니다. 필터와 찾기 모두에 완벽하게 작동합니다. 그리고 둘 다에 대한 WC3 문서에 따라 thisValue-선택 사항입니다. "this"값으로 사용할 함수에 전달할 값입니다. 이 매개 변수가 비어 있으면 "undefined"값이 "this"값으로 전달됩니다
richaa

1
@TarekEldeeb 당신이 할 객체를 전달합니다{one: 'haha', two:'hoho'}
toddmo

2
이것은 복잡성에 대한 답변 사이에 얼마나 큰 차이가있을 수 있는지 그리고 얼마나 복잡 할 수 있는지와 얼마나 단순 할 수 있는지에 대한 훌륭한 예입니다
toddmo

13

화살표 기능을 사용하는 ES6 대안을 찾는 사람들은 다음을 수행 할 수 있습니다.

let startsWith = wordToCompare => (element, index, array) => {
  return element.indexOf(wordToCompare) === 0;
}

// where word would be your argument
let result = addressBook.filter(startsWith("word"));

포함을 사용하여 업데이트 된 버전 :

const startsWith = wordToCompare => (element, index, array) => {
  return element.includes(wordToCompare);
}

요소, 색인 및 배열과 다른 매개 변수를 전달하는 방법이 있습니까? 예를 들어 X 변수를 전달하고 싶습니다.
leandrotk

이 경우 "wordToCompare"에 @leandrotk는 "X"변수가 전달되어야한다.
GetBackerZ

11
function startsWith(element, wordToCompare) {
    return element.indexOf(wordToCompare) === 0;
}

// ...
var word = "SOMETHING";

addressBook.filter(function(element){
    return startsWith(element, word);
});

4

다음과 같이 필터 내에서 화살표 기능을 사용할 수 있습니다.

result = addressBook.filter(element => element.indexOf(wordToCompare) === 0);

MDN의 화살표 기능

화살표 함수 표현식은 함수 표현식에 비해 구문이 짧고 this 값을 어휘 적으로 바인딩합니다 (자체 this, arguments, super 또는 new.target을 바인딩하지 않음). 화살표 함수는 항상 익명입니다. 이러한 함수 식은 메서드가 아닌 함수에 가장 적합하며 생성자로 사용할 수 없습니다.


참고 : IE에서 지원되지 않음
Luis Lavieri

1

왜 그들의 뚱뚱한 화살 기능이 무시하는지 궁금해하는 사람 [, thisArg], 예를 들어 왜

["DOG", "CAT", "DOG"].filter(animal => animal === this, "DOG") 보고 []

그것 때문에 this그 화살표 함수 함수가 생성 될 때 결합되고,의 값으로 설정되는 내부 this소위, 넓은 범위에 포괄 thisArg인수가 무시된다. 부모 범위에서 새 변수를 선언하여이 문제를 매우 쉽게 해결할 수 있습니다.

let bestPet = "DOG"; ["DOG", "CAT", "DOG"].filter(animal => animal === bestPet); => ["DOG", "DOG"]

다음은 더 많은 정보에 대한 링크입니다. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_separate_this


0

oddRaven 답변 및 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter 기반

나는 그것을 2 개의 다른 방법으로했다. 1) 기능 사용 방법. 2) 인라인 방식 사용.

//Here  is sample codes : 

var templateList   = [
{ name: "name1", index: 1, dimension: 1 }  ,
{ name: "name2", index: 2, dimension: 1 }  ,
{ name: "name3", index: 3, dimension: 2 }  ];


//Method 1) using function : 

function getDimension1(obj) {
                if (obj.dimension === 1) // This is hardcoded . 
                    return true;
                else return false;
            } 

var tl = templateList.filter(getDimension1); // it will return 2 results. 1st and 2nd objects. 
console.log(tl) ;

//Method 2) using inline way 
var tl3 = templateList.filter(element => element.index === 1 || element.dimension === 2  ); 
// it will return 1st and 3rd objects 
console.log(tl3) ;


0

필터 기능을 사용하고, 모든 매개 변수에 액세스하고, 지나치게 복잡하지 않은 쉬운 방법이 있습니다.

콜백의 thisArg 가 다른 범위 필터로 설정되지 않는 한 자체 범위를 생성하지 않으며 현재 범위 내에서 매개 변수에 액세스 할 수 있습니다. 필요한 경우 다른 값에 액세스하기 위해 다른 범위를 정의하도록 'this'를 설정할 수 있지만 기본적으로 호출 된 범위로 설정됩니다. 당신은 볼 수 이이 각도 범위에 사용되는 이 스택 .

indexOf를 사용하면 필터의 목적이 무너지고 더 많은 오버 헤드가 추가됩니다. 필터가 이미 배열을 통과하고 있는데 왜 다시 반복해야합니까? 대신 우리는 그것을 단순한 순수 함수로 만들 수 있습니다 .

다음은 상태에 items 라는 배열이있는 React 클래스 메서드 내의 사용 사례 시나리오 이며 필터를 사용하여 기존 상태를 확인할 수 있습니다.

checkList = (item) => {  // we can access this param and globals within filter
  var result = this.state.filter(value => value === item); // returns array of matching items

  result.length ? return `${item} exists` : this.setState({
    items: items.push(item) // bad practice, but to keep it light
  });
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.