web-dev-qa-db-ja.com

Math.max.apply()はどのように機能しますか?

Math.max.apply()はどのように機能しますか?.

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
  <script>
      var list = ["12","23","100","34","56",
                                    "9","233"];
      console.log(Math.max.apply(Math,list));    
  </script>
</body>
</html>

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max

上記のコードは、リスト内の最大数を見つけます。誰でも以下のコードがどのように機能するか教えてもらえますか? null or Math.を渡すと動作するようです

console.log(Math.max.apply(Math,list));

すべてのuser-defined/Native functionsには、使用できるcallおよびapplyメソッドがありますか?.

72
Shane

applyは配列を受け入れ、その配列をパラメーターとして実際の関数に適用します。そう、

Math.max.apply(Math, list);

として理解することができます、

Math.max("12", "23", "100", "34", "56", "9", "233");

したがって、applyは、データの配列をパラメーターとして関数に渡す便利な方法です。覚えている

console.log(Math.max(list));   # NaN

maxは配列を入力として受け入れないため、機能しません。

applyを使用することには別の利点があり、独自のコンテキストを選択できます。関数のapplyに渡す最初のパラメーターは、その関数内のthisになります。ただし、maxは現在のコンテキストに依存しません。したがって、Mathの代わりに何でも機能します。

console.log(Math.max.apply(undefined, list));   # 233
console.log(Math.max.apply(null, list));        # 233
console.log(Math.max.apply(Math, list));        # 233

applyは実際にはFunction.prototype で定義されているため、有効なJavaScript関数オブジェクトには、デフォルトでapply関数があります。

116
thefourtheye

JavaScript ES6では、 スプレッド演算子 を使用するだけです:

var list = ["12","23","100","34","56","9","233"];
console.log(Math.max(...list));
//                   ^^^ Spread operator 

誰でも以下のコードがどのように機能するか教えてもらえますか?

Math.max.apply(Math,list)

関数実装(本体)でMath参照として使用されるthisオブジェクトと、引数として渡されるlistオブジェクトを使用してMath.max関数を呼び出します。

だからこれは最終的に等しい

Math.max("12","23","100","34","56", "9","233")

NullまたはMathを渡すと動作するようです。

明らかにMath.max実装はインスタンス変数を使用しません-使用する理由はありません。ネイティブ実装は、argumentsを反復処理し、最大のものを見つけます。

すべてのユーザー定義/ネイティブ関数には、使用できるcallおよびapplyメソッドがありますか?.

はい、すべての関数はcallまたはapplyを使用して呼び出すことができます

参照:

17
zerkms

Math.max(val1、val2、...)

Math.max(1, 2, 3); // Math.max([value1[, value2[, ...]]])
value1, value2...はパラメーターであり、数値でなければなりません MDN Math.max

arrayMath.maxパラメーターとして渡すことはできません。配列を渡すには、applyを使用する必要があります。

適用する

Applyの最初のパラメーターはthisで、2番目はarrayです。数学メソッドは他の言語の静的メソッドに相当します。つまり、array.prototype.sliceとは異なり、オブジェクトインスタンスを必要としないため、この場合thisを渡す必要はありません。

var arr = [1, 2, 3];

Math.max(1, 2, 3);  // -> 3
Math.max(arr);      // -> NaN (Not a Number)
Math.max.apply(null, arr);  // Math.max.apply(null, [1, 2, 3]) -> Math.max(1, 2, 3) -> 3

arr.slice(1);  // -> returns Array [2, 3]
Array.prototype.slice.call(arr, 1); // Array.prototype.slice.call([1, 2, 3], 1) == [1, 2, 3].slice(1)

配列をパラメーターとして渡す場合は、applyを使用する必要があります。そうでない場合は、callを使用します。

apply =array
call =comma区切り
呼び出しと適用の詳細

1
rafr3

Math.max(...numbers)Function.prototype.apply()は、比較的要素の少ない配列にのみ使用すべきだと言うことから始めます。 (...)配列が大きすぎる場合、適用は失敗するか、間違った結果を返します

Math.max.apply(null | undefined | Math, numbers)Math.max(...numbers)と同じなので、審美的な理由からMath.max(...numbers)をお勧めします。

const numbers = [5, 6, 2, 3, 7];

const max = Math.max(...numbers);

console.log('max:', max);
// expected output: 7

const min = Math.min(...numbers);

console.log('min:', min);
// expected output: 2

非常に大きな数値配列で最大要素を見つける必要がある場合:Array.reduce()メソッドを使用します。

Array.reduce()を使用して、各値を比較することにより、数値配列の最大要素を見つけることができます。

const numbers = [5, 6, 2, 3, 7];
const getMax = (numbers) => numbers.reduce((a, b) => Math.max(a, b));

const getMin = (numbers) => numbers.reduce((a, b) => Math.min(a, b));
        
const max = getMax(numbers)
const min = getMin(numbers)

console.log('max:', max)
console.log('min:', min)

結論:

比較的小さな数値配列:Math.max(...numbers)を使用します非常に大きな数値配列:Array.reduce()メソッドを使用します

1
voxun