internet-explorer array - Internet Explorer 브라우저 용 JavaScript에서 배열 indexOf()를 수정하는 방법




remove value (9)

underscore.js 라이브러리에는 대신 사용할 수있는 indexOf 함수가 있습니다.

_.indexOf([1, 2, 3], 2)

JavaScript를 사용하여 작업 한 적이 있다면 Internet Explorer가 Array.prototype.indexOf () [Internet Explorer 8 포함]에 대한 ECMAScript 함수를 구현하지 않음을 알고 있습니다. 다음 코드를 사용하여 페이지의 기능을 확장 할 수 있기 때문에 큰 문제는 아닙니다.

Array.prototype.indexOf = function(obj, start) {
     for (var i = (start || 0), j = this.length; i < j; i++) {
         if (this[i] === obj) { return i; }
     }
     return -1;
}

언제 이것을 구현해야합니까?

프로토 타입 함수가 있는지 확인하고 그렇지 않으면 배열 프로토 타입을 확장하는 다음 검사를 사용하여 모든 페이지에이 코드를 래핑해야합니까?

if (!Array.prototype.indexOf) {

    // Implement function here

}

아니면 브라우저 검사를하고 Internet Explorer가 아니면 구현합니까?

//Pseudo-code

if (browser == IE Style Browser) {

     // Implement function here

}

전체 코드는 다음과 같습니다.

if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(obj, start) {
         for (var i = (start || 0), j = this.length; i < j; i++) {
             if (this[i] === obj) { return i; }
         }
         return -1;
    }
}

정말 철저한 대답과 이것뿐만 아니라 다른 배열 함수에 대한 코드는 질문 Internet Explorer (indexOf, forEach 등)에서 JavaScript 배열 함수를 고정 체크 아웃하십시오.


이걸 좋아합니까?

if (!Array.prototype.indexOf) {

}

MDC의 권장 호환성 .

일반적으로 브라우저 탐지 코드는 큰 no-no입니다.


이것은 내 구현이었다. 기본적으로 페이지의 다른 스크립트보다 먼저 추가하십시오. 즉 인터넷 익스플로러 8의 글로벌 솔루션에 대한 마스터에서. 또한 프레임 워크의 할당량에 사용되는 것 같은 트림 기능을 추가했습니다.

<!--[if lte IE 8]>
<script>
    if (!Array.prototype.indexOf) {
        Array.prototype.indexOf = function(obj, start) {
            for (var i = (start || 0), j = this.length; i < j; i++) {
                if (this[i] === obj) {
                    return i;
                }
            }
            return -1;
        };
    }

    if(typeof String.prototype.trim !== 'function') {
        String.prototype.trim = function() {
            return this.replace(/^\s+|\s+$/g, '');
        };
    };
</script>
<![endif]-->

그것은 나를 위해 작동합니다.

if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(elt /*, from*/) {
    var len = this.length >>> 0;

    var from = Number(arguments[1]) || 0;
    from = (from < 0)? Math.ceil(from) : Math.floor(from);
    if (from < 0)
    from += len;

    for (; from < len; from++) {
      if (from in this && this[from] === elt)
        return from;
    }
    return -1;
  };
}

Mozilla 공식 솔루션이 있습니다. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf

(function() {
    /**Array*/
    // Production steps of ECMA-262, Edition 5, 15.4.4.14
    // Reference: http://es5.github.io/#x15.4.4.14
    if (!Array.prototype.indexOf) {
        Array.prototype.indexOf = function(searchElement, fromIndex) {
            var k;
            // 1. Let O be the result of calling ToObject passing
            //    the this value as the argument.
            if (null === this || undefined === this) {
                throw new TypeError('"this" is null or not defined');
            }
            var O = Object(this);
            // 2. Let lenValue be the result of calling the Get
            //    internal method of O with the argument "length".
            // 3. Let len be ToUint32(lenValue).
            var len = O.length >>> 0;
            // 4. If len is 0, return -1.
            if (len === 0) {
                return -1;
            }
            // 5. If argument fromIndex was passed let n be
            //    ToInteger(fromIndex); else let n be 0.
            var n = +fromIndex || 0;
            if (Math.abs(n) === Infinity) {
                n = 0;
            }
            // 6. If n >= len, return -1.
            if (n >= len) {
                return -1;
            }
            // 7. If n >= 0, then Let k be n.
            // 8. Else, n<0, Let k be len - abs(n).
            //    If k is less than 0, then let k be 0.
            k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
            // 9. Repeat, while k < len
            while (k < len) {
                // a. Let Pk be ToString(k).
                //   This is implicit for LHS operands of the in operator
                // b. Let kPresent be the result of calling the
                //    HasProperty internal method of O with argument Pk.
                //   This step can be combined with c
                // c. If kPresent is true, then
                //    i.  Let elementK be the result of calling the Get
                //        internal method of O with the argument ToString(k).
                //   ii.  Let same be the result of applying the
                //        Strict Equality Comparison Algorithm to
                //        searchElement and elementK.
                //  iii.  If same is true, return k.
                if (k in O && O[k] === searchElement) {
                    return k;
                }
                k++;
            }
            return -1;
        };
    }
})();

if (!Array.prototype.indexOf) 사용하여 정의되지 않았는지 확인해야합니다.

또한 indexOf 구현이 올바르지 않습니다. if (this[i] == obj) 문에서 == 대신 === 를 사용해야하며, 그렇지 않으면 [4,"5"].indexOf(5) 는 구현에 따라 1이 될 것이며 이는 올바르지 않습니다.

MDC에서 구현을 사용 하는 것이 좋습니다.


Underscore.js로

var arr=['a','a1','b'] _.filter(arr, function(a){ return a.indexOf('a') > -1; })


나는 이것이 오래된 게시물 인 것을 알고 있으며 이미 많은 훌륭한 답변들이 있습니다. 좀 더 완벽을 위해 AngularJS 사용하여 다른 것을 던질 것이라고 생각했습니다. 물론 이것은 Angular를 사용하는 경우에만 적용됩니다. 그럼에도 불구하고 어쨌든 그것을 넣고 싶습니다.

angular.forEach 는 두 개의 인수와 선택적 인 세 번째 인수를 취합니다. 첫 번째 인수는 반복 할 객체 (배열)이고 두 번째 인수는 반복 함수이며 선택적 세 번째 인수는 객체 컨텍스트입니다 (기본적으로 'this'로 루프 내에서 참조됩니다.).

각 회진 forEach 루프를 사용하는 여러 가지 방법이 있습니다. 가장 간단하고 아마도 가장 많이 사용되는 것은

var temp = [1, 2, 3];
angular.forEach(temp, function(item) {
    //item will be each element in the array
    //do something
});

한 배열에서 다른 배열로 항목을 복사하는 데 유용한 또 다른 방법은

var temp = [1, 2, 3];
var temp2 = [];
angular.forEach(temp, function(item) {
    this.push(item); //"this" refers to the array passed into the optional third parameter so, in this case, temp2.
}, temp2);

그래도 할 필요는 없지만 다음과 같이하면됩니다. 앞의 예와 같습니다.

angular.forEach(temp, function(item) {
    temp2.push(item);
});

이제 angular.forEach내장 된 바닐라 맛의 for루프 에 반대 되는 기능 을 사용하는 것이 장단점이 있습니다 .

찬성

  • 쉬운 가독성
  • 간편한 쓰기 기능
  • 사용 가능한 경우 angular.forEachES5 forEach 루프를 사용합니다. 이제 각 for 루프는 for 루프보다 훨씬 느리기 때문에 cons 섹션에서 효율적으로 처리 할 것입니다. 일관되고 표준화 된 것이 좋기 때문에 이것을 프로로 언급합니다.

다음과 같은 두 개의 중첩 루프를 생각해보십시오. 정확히 같은 일을합니다. 우리가 2 개의 객체 배열을 가지고 있고 각 객체가 결과 배열을 포함한다고 가정 해 봅시다. 각각의 문자열은 Value 속성을 가지고 있습니다. 그리고 각각의 결과를 반복 할 필요가 있다고 가정 해 봅시다. 평등 한 경우 몇 가지 작업을 수행하십시오.

angular.forEach(obj1.results, function(result1) {
    angular.forEach(obj2.results, function(result2) {
        if (result1.Value === result2.Value) {
            //do something
        }
    });
});

//exact same with a for loop
for (var i = 0; i < obj1.results.length; i++) {
    for (var j = 0; j < obj2.results.length; j++) {
        if (obj1.results[i].Value === obj2.results[j].Value) {
            //do something
        }
    }
}

이것은 매우 단순한 가상의 예제이지만, 두 번째 접근법을 사용하여 루프에 3 중 임베디드를 작성 했으므로이 내용을 읽거나 쓰는 것이 매우 어려웠습니다.

단점

  • 능률. angular.forEach그리고 기본은 forEach, 그 문제에 관해서는, 모두 너무 느린 정상보다 for루프 .... 약 90 % 느린 . 따라서 대규모 데이터 세트의 경우 기본 for루프 를 유지하는 것이 가장 좋습니다 .
  • 휴식을 취하거나 계속하거나 지원을받지 마십시오. continue실제로 " accident "에 의해 지원됩니다 , angular.forEach당신 은 그 반복에 대한 함수에서 벗어나지 못하게하는 return;것과 같은 함수에 문장을 넣는 angular.forEach(array, function(item) { if (someConditionIsTrue) return; });것을 계속합니다. 이것은 네이티브 forEach가 중단을 지원하지 않거나 계속할 수도 없기 때문 입니다.

다른 여러 장단점이있을 것이라고 확신합니다. 여러분이 적합하다고 생각하는 것을 추가해 주시기 바랍니다. 나는 결론을 내릴 수 있습니다. 효율성이 필요하다면, for당신의 반복적 인 요구에 맞게 네이티브 루프를 고수 해야합니다. 그러나 데이터 집합이 더 작고 가독성과 쓰기 기능을 대신해서 포기하는 것이 좋을 경우, 그 angular.forEach나쁜 소년을 던지십시오 .





javascript internet-explorer internet-explorer-8 cross-browser