Javascript 有人能解释一下这个Array.prototype.find()polyfill吗?

Javascript 有人能解释一下这个Array.prototype.find()polyfill吗?,javascript,arrays,Javascript,Arrays,在这个MDN页面上[ 这里有一个polyfill: if (!Array.prototype.find) { Object.defineProperty(Array.prototype, 'find', { enumerable: false, configurable: true, writable: true, value: function(predicate) { if (this == null) { throw new

在这个MDN页面上[ 这里有一个polyfill:

if (!Array.prototype.find) {
  Object.defineProperty(Array.prototype, 'find', {
    enumerable: false,
    configurable: true,
    writable: true,
    value: 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++) {
        if (i in list) {
          value = list[i];
          if (predicate.call(thisArg, value, i, list)) {
            return value;
          }
        }
      }
      return undefined;
    }
  });
}

既然
这个
肯定是一个数组(我们正在扩充array.prototype),那么为什么要确保
长度
是数字的,为什么要使用Object()?

基本答案是polyfill只是忠实地实现了ES6草案规范中算法的第1步和第4步(§22.1.3.8,从5月22日草案开始)

1.让O作为调用ToObject的结果,将this值作为参数传递

4.让len为ToLength(lenValue)

(其中ToLength基本上是一个数字的转换。)

由于现在可以为
这个
使用非对象值(通过
函数#调用
函数#应用
,或者通过在严格模式下直接调用函数),步骤1是有意义的

既然
这个
肯定是一个数组(我们正在扩充
数组.prototype
),那么为什么要确保长度是数字的,为什么要使用
Object()

但是我们不知道
这个
是一个数组。请参阅当前ES6规范草案中的注释:

find
函数是有意泛型的;它不要求它的
this
值是数组对象。因此,它可以传输到其他类型的对象以用作方法。能否将
find
函数成功应用于非数组的外来对象取决于实现

您可以在几乎所有分配给原型的预定义函数中找到该注释

例如,您可以通过将它们直接分配给对象或其他原型,将它们用于其他用途:

MyNiftyThing.prototype.find = Array.prototype.find;
…或通过或

因此,假设我想在
arguments
对象上使用
数组#find
arguments
当然类似于数组,但不是数组。因此我可以这样做:

function foo() {
    var firstObject = Array.prototype.find.call(arguments, function(val) {
        return typeof val === "object";
    });
    // ...
}
一个更著名的示例(不涉及
find
)用于将类似数组的对象转换为数组:

function foo() {
    // Turn the `arguments` pseudo-array into a real array
    var args = Array.prototype.slice.call(arguments, 0);
}

此polyfill的问题在于它需要Object.defineProperty方法,这在未实现find的旧浏览器中不可用。如答案所示;
不能保证是数组,您可以在以下答案中看到此
可以是什么(如果您需要比T.J.提供的更多信息):(在该变量的
下)
function foo() {
    // Turn the `arguments` pseudo-array into a real array
    var args = Array.prototype.slice.call(arguments, 0);
}