使用 array.every() 方法的 JavaScript 箭头函数中 (x => x) 的含义

Meaning of (x => x) in JavaScript arrow function using array.every() method

寻找关于这行代码的解释。我在一定程度上了解箭头功能。此代码 snippet/challenge 的目的是; “给定任意数量的参数,如果 none 个参数为假,则 return 为真。”我见过这样的解决方案:

const nothingIsNothing = (...args) => args.every(x => x)

参数示例和预期结果为:

nothingIsNothing(0, false, undefined, null) ➞ false

nothingIsNothing(33, "Hello",  true,  []) ➞ true

nothingIsNothing(true, false) ➞ false

我只是不明白 (x => x) 部分是如何评估为真值或假值的。有人可以解释这是如何工作的吗?我希望这是有道理的,哈哈。谢谢!

使用 .every,如果回调中的任何 return 值是假的,.every 的计算结果为 false,否则计算结果为 true.所以 x => x 作为回调意味着:获取数组中的每个值并立即 return 它。如果全部为真,则整个 .every 的计算结果为 true,否则为 false.

它的逻辑与此相同:

const nothingIsNothing = (...args) => {
  for (const arg of args) {
    if (!arg) return false;
  }
  return true;
};

或者,自己实现类似于 .every 的东西:

// don't do this in real code, this is just an example

Array.prototype.myEvery = function(callback) {
  for (const item of this) {
    if (!callback(item)) return false;
  }
  return true;
};

console.log([1, 2, 3].myEvery(x => x));
console.log([1, 2, 3, 0].myEvery(x => x));

它是几件事的组合

  1. Javascript 隐式 return 语句。

getVal = a => a;

相同
function getVal(a) { return a }
  1. 每个网络 API 方法 运行 直到它遇到 falsy(不是假的)值。下面引用自 MDN。

The every method executes the provided callback function once for each element present in the array until it finds the one where callback returns a falsy value. If such an element is found, the every method immediately returns false. Otherwise, if callback returns a truthy value for all elements, every returns true.

param => param 等同于 (param) => { return param }

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

这些都是 JavaScript 中的所有虚假值:https://developer.mozilla.org/en-US/docs/Glossary/Falsy

every 的 return 值的文档说明如下:

true if the callback function returns a truthy value for every array element. Otherwise, false.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every

所以这样的事情是错误的,因为并非所有元素都是真实的

const x = ['test', 0, null, -0].every(el => el);
console.log(x);

但是像这样的东西会 return 为真,因为所有元素都是真值

const x = ['test', 1, 'hi', 10].every(el => el);
console.log(x);

根据每个数组元素的 docs the every() method tests whether all elements in the array pass the test implemented by the provided function. It returns a Boolean value i.e true if the callback function returns a truthy 值。否则,false.

const nothingIsNothing = (...args) => args.every(x=>x)可以展开为:

const nothingIsNothing = (...args) => args.every(function(x){
if(x)
  return true
else 
  return false
})

这是另一个版本,可以帮助您更好地理解 shorthand。值 x 被类型转换为布尔值并返回 true/false 。

const nothingIsNothing = (...args) => args.every(Boolean)
console.log(nothingIsNothing(0, false, undefined, null))
console.log(nothingIsNothing(33, "Hello",  true,  []))

Array.prototpe.every() 负责这里的繁重工作。

The every() method tests whether all elements in the array pass the test implemented by the provided function. It returns a Boolean value.

遵循 ECMA-262 第 5 规范的 PolyFil,假设 Object 和 TypeError 具有其原始值,并且 callbackfn.call 计算为 Function.prototype.call 的原始值,很好地演示了内部行为:

Array.prototype.PolyFillEvery = function(callbackfn, thisArg) {
  'use strict';
  var T, k;

  if (this == null) {
    throw new TypeError('this is null or not defined');
  }

  // 1. Let O be the result of calling ToObject passing the this 
  //    value as the argument.
  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 IsCallable(callbackfn) is false, throw a TypeError exception.
  if (typeof callbackfn !== 'function' && Object.prototype.toString.call(callbackfn) !== '[object Function]') {
    throw new TypeError();
  }

  // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
  if (arguments.length > 1) {
    T = thisArg;
  }

  // 6. Let k be 0.
  k = 0;

  // 7. Repeat, while k < len
  while (k < len) {

    var kValue;

    // 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
    if (k in O) {
      var testResult;
      // i. Let kValue be the result of calling the Get internal method
      //    of O with argument Pk.
      kValue = O[k];

      // ii. Let testResult be the result of calling the Call internal method 
      // of callbackfn with T as the this value if T is not undefined 
      // else is the result of calling callbackfn 
      // and argument list containing kValue, k, and O.
      if(T) testResult = callbackfn.call(T, kValue, k, O); 
      else testResult = callbackfn(kValue,k,O)

      // iii. If ToBoolean(testResult) is false, return false.
      if (!testResult) {
        return false;
      }
    }
    k++;
  }
  return true;
};

const arFalsey = [0, false, undefined, null];
const arTruthy = [33, "Hello",  true,  []];

console.log(arFalsey.PolyFillEvery(x=>x)); //false
console.log(arTruthy.PolyFillEvery(x=>x)); //true
console.log([true,false].PolyFillEvery(x=>x)); //false

循环内部的关键部分是if-clause:

// iii. If ToBoolean(testResult) is false, return false.
if (!testResult) {
  return false;
}

一旦其中一个元素未被测试为真 false 就会被 returned; spread (...) 表达式仅用于迭代数组,而不是传统函数,箭头函数 x => x 用于馈送(通过 return)每个元素以供测试在 every 函数中。