47

この構文を可能にしたい:

var a = add(2)(3); //5

http://dmitry.baranovskiy.com/post/31797647で読んだ内容に基づく

それを可能にする方法がわかりません。

4

31 に答える 31

39
function add(x) {
    return function(y) {
        return x + y;
    };
}

ああ、JavaScript の美しさ

この構文もかなりきれいです

function add(x) {
    return function(y) {
        if (typeof y !== 'undefined') {
            x = x + y;
            return arguments.callee;
        } else {
            return x;
        }
    };
}
add(1)(2)(3)(); //6
add(1)(1)(1)(1)(1)(1)(); //6
于 2010-02-16T12:52:01.653 に答える
15
function add(x){
  return function(y){
    return x+y
  }
}

ファーストクラスの関数クロージャーがその役割を果たします。

于 2010-02-16T12:50:20.697 に答える
14

それはJSカリングについてであり、少し厳密valueOfです:

function add(n){
  var addNext = function(x) {
    return add(n + x);
  };

  addNext.valueOf = function() {
    return n;
  };

  return addNext;
}

console.log(add(1)(2)(3)==6);//true
console.log(add(1)(2)(3)(4)==10);//true

無制限の追加チェーンでチャームのように機能します!!

于 2018-07-13T03:20:39.463 に答える
13

add(2)(3) と add(2,3) の 2 つの方法で役に立ちます。

1.)

 function add(a){ return function (b){return a+b;} }

    add(2)(3) // 5

2.)

function add(a,b){
        var ddd = function (b){return a+b;};
        if(typeof b =='undefined'){
            return ddd;
        }else{
            return ddd(b);
        }
    }

add(2)(3) // 5
add(2,3) // 5
于 2014-12-12T13:25:54.103 に答える
12
function add(n) {
  sum = n;
  const proxy = new Proxy(function a () {}, {
    get (obj, key) {
      return () => sum;
    },
    apply (receiver, ...args) {
      sum += args[1][0];
      return proxy;
    },
  });
  return proxy
}

すべてに対して機能し、他のソリューションのように関数の最後に最後の () を必要としません。

console.log(add(1)(2)(3)(10));    // 16
console.log(add(10)(10));         // 20
于 2016-10-14T21:41:59.823 に答える
11

ES6 構文により、これは素晴らしくシンプルになります。

const add = (a, b) => a + b;

console.log(add(2, 5)); 
// output: 7

const add2 = a => b => a + b;

console.log(add2(2)(5));
// output: 7
于 2016-10-24T19:54:46.043 に答える
4

これは、add(2,3)()、add(2)(3)()、または add(2,1,3)(1)(1)(2,3)( のような任意の組み合わせを解決する一般化されたソリューションです。 4)(4,1,1)()。セキュリティチェックはほとんど行われておらず、さらに最適化できることに注意してください。

function add() {
	var total = 0;

	function sum(){
		if( arguments.length ){
			var arr = Array.prototype.slice.call(arguments).sort();
			total = total + arrayAdder(arr);
			return sum;
		}
		else{
			return total;
		}
	}

	if(arguments.length) {
		var arr1 = Array.prototype.slice.call(arguments).sort();
		var mytotal = arrayAdder(arr1);
		return sum(mytotal);
	}else{
		return sum();
	}

	function arrayAdder(arr){
		var x = 0;
		for (var i = 0; i < arr.length; i++) {
			x = x + arr[i];
		};
		return x;
	}
}
add(2,3)(1)(1)(1,2,3)();

于 2016-01-10T09:04:01.917 に答える
3

すでに述べたことに加えて、一般的なカリー化を使用したソリューションを次に示します ( http://github.com/sstephenson/prototype/blob/master/src/lang/function.js#L180に基づく)

Function.prototype.curry = function() {
    if (!arguments.length) return this;
    var __method = this, args = [].slice.call(arguments, 0);
    return function() {
      return __method.apply(this, [].concat(
        [].slice.call(args, 0),
        [].slice.call(arguments, 0)));
   }
}


add = function(x) {
    return (function (x, y) { return x + y }).curry(x)
}

console.log(add(2)(3))
于 2010-02-16T13:55:21.277 に答える
2

この場合、CLOSURES の概念を使用できます。
関数「add」は別の関数を返します。返される関数は、親スコープの変数 (この場合は変数 a) にアクセスできます。

function add(a){

    return function(b){
        console.log(a + b);
    }

}


add(2)(3);

クロージャーを理解するためのリンクは次のとおりですhttp://www.w3schools.com/js/js_function_closures.asp

于 2016-05-28T18:13:10.743 に答える
1
function add(a, b){
 return a && b ? a+b : function(c){return a+c;}
}

console.log(add(2, 3));
console.log(add(2)(3));
于 2016-08-27T21:40:14.207 に答える
1

この質問はすでに非常に多くの回答の動機となっているため、私の「2 ペニーの価値」は確かに物事を台無しにすることはありません。

「お気に入り」の機能、つまり、そのようなカリー化関数で見つけたい機能を ES6 表記法を使用してまとめようとした多数のアプローチとバリエーションに驚かされました。

const add=(...n)=>{
 const vsum=(a,c)=>a+c;
 n=n.reduce(vsum,0);
 const fn=(...x)=>add(n+x.reduce(vsum,0));
 fn.toString=()=>n; 
 return fn;
}

let w=add(2,1); // = 3
console.log(w()) // 3
console.log(w); // 3
console.log(w(6)(2,3)(4)); // 18
console.log(w(5,3)); // 11
console.log(add(2)-1); // 1
console.log(add()); // 0
console.log(add(5,7,9)(w)); // 24
.as-console-wrapper {max-height:100% !important; top:0%}

基本的に、この再帰的にプログラムされた関数には何も新しいものはありません。ただし、上記の回答のいずれかに記載されている引数のすべての可能な組み合わせで機能し、最後に「空の引数リスト」は必要ありません

必要な数のカリー化レベルで必要な数の引数を使用でき、その結果、同じ目的で再利用できる別の関数が生成されます。ちょっとした「トリック」を使って「同時に」数値.toString()取得しました。内部関数の関数を再定義しましたfn。このメソッドは、関数が引数リストなしで使用され、「何らかの値が期待される」ときはいつでも Javascript によって呼び出されます。技術的には、文字列ではなく数値を返すため、これは「ハック」ですが、ほとんどの場合「望ましい」方法で機能します。やってみよう!

于 2020-07-23T05:58:19.110 に答える
1

これも試すことができます:

let sum = a => b => b ? sum(a + b) :a
console.log(sum(10)(20)(1)(32)())   //63
于 2021-06-30T20:26:25.383 に答える
0

内部関数は親関数のパラメーターアクセスにアクセスし、そのレキシカルスコープに保存します。実行すると、答えが得られます

    const Sum = function (a) {
        return function (b) {
            return b ? Sum(a + b) : a;
        }
    };

    Sum(1)(2)(3)(4)(5)(6)(7)() // result is 28
    Sum(3)(4)(5)() // result is 12
    Sum(12)(10)(20) // result is 42

ここに画像の説明を入力

于 2019-12-06T09:26:03.917 に答える
0

ここでは、メイン関数 iter 内で呼び出されるすべての関数がxを参照および更新するというクロージャの概念を使用します。ループがどれだけ長くても、最後の関数までxにアクセスできます。

function iter(x){    
return function innfunc(y){
//if y is not undefined
if(y){
//closure over ancestor's x
x = y+x;
return innfunc;
}
else{
//closure over ancestor's x
return x;
    }
  }
}

iter(2)(3)(4)() //9 iter(1)(3)(4)(5)() //13

于 2019-07-21T16:51:04.770 に答える
-1

function add () {
    var args = Array.prototype.slice.call(arguments);
 
    var fn = function () {
        var arg_fn = Array.prototype.slice.call(arguments);
        return add.apply(null, args.concat(arg_fn));
    }
 
    fn.valueOf = function () {
        return args.reduce(function(a, b) {
            return a + b;
        })
    }
 
    return fn;
}

console.log(add(1));
console.log(add(1)(2));
console.log(add(1)(2)(5));

http://www.cnblogs.com/coco1s/p/6509141.htmlから

于 2017-04-28T03:17:31.650 に答える