【问题标题】:Polyfill for Array.includes checking NaNPolyfill for Array.includes 检查 NaN
【发布时间】:2019-09-28 05:52:53
【问题描述】:

所以首先这不是我面临的问题。当我遇到.indexOf and .includes的Array原型方法时,我正在浏览一些Javascript的博客。因此,如果一个数组有NaN 作为值,那么indexOf 可能无法计算出来,我只能使用.includes。但我的问题是,既然includes 的浏览器兼容性实际上不包括IE,那么检测NaN 检查的替代方法应该是什么?我想通过引用this来构建一个polyfill

if (Array.prototype.includes) {
  Object.defineProperty(Array.prototype, "includes", {
    enumerable: false,
    value: function(obj) {
        var newArr = this.filter(function(el) {
          return el == obj;
        });
        return newArr.length > 0;
      }
  });
}

var arr = [NaN];
console.log(arr.includes(NaN));

但不幸的是,它也返回 false。那么我还有什么其他选择?还是我错过了什么?

【问题讨论】:

  • 你可以使用arr.findIndex()找到NaN的索引
  • includes() 的 polyfill 可以是 found on MDN
  • @VLAZ 我一开始也是这么想的,但事实并非如此!请参阅 ecma-international.org/ecma-262/7.0/#sec-samevaluezeroNaN 是一个例外。 If x is NaN and y is NaN, return true.
  • @CertainPerformance 是的,看来我在这里错了。出于某种原因,我认为我过去什至使用过[NaN].includes(NaN) 并获得了false。无论如何,MDN的实现应该是正确的
  • 请注意,您的 polyfill 可能应该将 if (Array.prototype.includes) { 更改为 if (!Array.prototype.includes) {

标签: javascript arrays nan polyfills


【解决方案1】:

您也可以为 Number.isNaN 添加一个 polyfill,然后在您的 filter 测试中使用它 - 如果 objel 都通过 Number.isNaN,则返回 true:

Number.isNaN = Number.isNaN || function(value) {     
    return value !== value;
}

// if (!Array.prototype.includes) {
  Object.defineProperty(Array.prototype, "includes", {
    enumerable: false,
    value: function(obj) {
        var newArr = this.filter(function(el) {
          return el == obj || Number.isNaN(el) && Number.isNaN(obj);
        });
        return newArr.length > 0;
      }
  });
// }

var arr = [NaN];
console.log(arr.includes(NaN));

【讨论】:

    【解决方案2】:

    Array#includes 使用同值零算法,== 相同。

    Same-Value 由Object.is() 提供,您可以手动检查-0+0 以获得检查的“-Zero”部分。

    链接页面包含一个 polyfill,尽管由于 polyfill 包含一个使 -0+0 不同的步骤 - 在相同值零算法中您不希望这样做 - 您可以将其省略并相应地简化:

    function SameValueZero(x, y) {
        return x === y || (x !== x && y !== y);
    }
    

    【讨论】:

      【解决方案3】:

      您可以使用firstIndex 找到NaN 的索引。试试这样。

      var arr = [NaN];
      let index = arr.findIndex(Number.isNaN)
      console.log(index >= 0);

      【讨论】:

      • 如果includes 必须被填充,那么我怀疑findIndexNumber.isNaN 是否可用。
      • 另外,(index >= 0)?true:false 是完全多余的。 index >= 0 返回一个布尔值,所以如果返回的布尔值是true,则三元组返回...true。如果布尔值为false,则返回false
      • @VLAZ 哦,对不起,我错过了!!
      • 虽然这提供了答案,正如@VLAZ 提到的,findIndexNumber.isNaN 在 IE 中不受支持:(
      猜你喜欢
      • 2011-03-27
      • 2010-10-30
      • 2013-04-14
      • 2020-09-29
      • 2013-06-03
      相关资源
      最近更新 更多