2014-10-10 76 views
4

可用数组原型我有一个Array.find()填充工具,我从MDN中的forEach

了我目前在测试的浏览器没有为它使填充工具的运行和功能的支持,因为预期。然而,我有一个插件是foreach通过它我最后一个元素是功能find

这是怎么发生的?

另外,当我在Chrome的DevTools中检查数组时,我得到以下结果。

if (!Array.find) { 
 
    $('<h5>This browser doesnt support Array.find</h5>').appendTo('body'); 
 
} 
 

 
if (!Array.prototype.find) { 
 
    Array.prototype.find = function(predicate) { 
 
    if (this == null) { 
 
     throw new TypeError('Array.prototype.find called on null or undefined'); 
 
    } 
 
    if (typeof predicate !== 'function') { 
 
     throw new TypeError('predicate must be a function'); 
 
    } 
 
    var list = Object(this); 
 
    var length = list.length >>> 0; 
 
    var thisArg = arguments[1]; 
 
    var value; 
 

 
    for (var i = 0; i < length; i++) { 
 
     value = list[i]; 
 
     if (predicate.call(thisArg, value, i, list)) { 
 
     return value; 
 
     } 
 
    } 
 
    return undefined; 
 
    }; 
 
} 
 

 
var someArray = [{name: 'something'}, {name: 'something else'}]; 
 

 
someArray.forEach(function (item, index) { 
 
    $('<h4>'+ item.name +'</h4>').appendTo('body'); 
 
}); 
 

 
var extended = $.extend({}, [], someArray); 
 

 
$.each(extended, function (index, item) { 
 
    $('<h4>'+ item.name +'</h4>').appendTo('body'); 
 
}); 
 

 
if (extended.find) { 
 
    $("<div>Notice that we now have in extended the function find<div>").appendTo('body'); 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

enter image description here

注意find__proto__是粉红色的比其它proto的暗的阴影。

任何想法?

+0

在所有浏览器中都一样吗? – 2014-10-10 14:56:29

+0

发生了什么浏览器,你能提供代码块在哪里发生? – bigtunacan 2014-10-10 14:58:34

+1

你在数组上执行'for..in'吗?你不应该这样做(至少不是没有'.hasOwnProperty()'调用)。 – 2014-10-10 15:06:21

回答

4

您的foreach扩展名正在检查密钥但未检查它们是对象的自有属性。也就是说,该代码:

Array.prototype.x = 3; 
var test = [1]; 
for (var key in test) { 
    console.log(key); 
} 

...将记录都0x因为x[]可枚举密钥是不是[]的自有财产。为了解决这个问题,你可以修补foreach代码来检查只有自己的属性:

Array.prototype.x = 3; 
var test = [1]; 
for (var key in test) { 
    if (test.hasOwnProperty(key)) { 
     console.log(key); 
    } 
} 

或者你也可以改变你把钥匙上的原型,顺便让像原型的其他按键,它不是可以枚举的。修订后的poyfill是:

(function() { // scope bracket; hides `find` from global scope. 
    function find(predicate) { 
     if (this == null) { 
      throw new TypeError('Array.prototype.find called on null or undefined'); 
     } 
     if (typeof predicate !== 'function') { 
      throw new TypeError('predicate must be a function'); 
     } 
     var list = Object(this), length = list.length >>> 0, thisArg = arguments[1], value, i; 
     for (i = 0; i < length; i++) { 
      value = list[i]; 
      if (predicate.call(thisArg, value, i, list)) { 
        return value; 
      } 
     } 
     return undefined; 
    }; 
    if (!Array.prototype.find) { 
     if (Object.defineProperty) { 
      Object.defineProperty(Array.prototype, 'find', {value: find, enumerable: false}); 
     } else { 
      Array.prototype.find = find; 
     } 
    } 
}()); 

如果你的浏览器不支持Array.prototype.find,然而,有一个机会,它并没有像以前那样支持Object.defineProperty,让你回到了同一个地方。然后,您需要希望它不会太旧,以至于缺少.hasOwnProperty()测试,您需要修改foreach函数。 (Array.prototype.find()函数是ECMAScript 6草案的一部分; Object.defineProperty()在ECMAScript 5.1中进行了标准化,而Object.prototype.hasOwnProperty()是ECMAScript 3. ES5。1在2011年发布,只要你的浏览器只有几年的时间,上述内容应该适合你 - 特别是如果你使用的是Opera或IE,那些没有新的ES6 .find()但是,他们有Object.defineProperty

+1

Bingo Bango Bongo。你先生用那个修改后的polyfill为我赢得了互联网。谢谢。 – 2014-10-10 15:22:07

2

Google Chrome会将添加的方法变暗但尚未成为其中的一部分。

做这个

Array.prototype.hi = function() {} 

然后做

console.log(Array.prototype); 

你会看到hi变暗。由于find还不是Array.prototype的一部分,但在执行代码后变成了一个,它变暗了,hi变暗了。

+2

很有意义...谢谢 – 2014-10-10 15:06:12