доступ к аргументам внешней вызывающей функции

Я хочу написать функцию, которая принимает функцию и некоторые другие объекты в качестве аргументов, делает эти аргументы аргументами по умолчанию для функции и возвращает новую функцию.

Предположим, у нас есть drawRect(x, y, x2, y2). Я хочу написать функцию с именем «partial», чтобы

(partial(drawRect, 0, 0))(x2, y2);

быть равным

drawRect(0, 0, x2, y2);

обратите внимание, что я хочу, чтобы функция partial была гибкой, поэтому она принимает любую функцию и любое количество аргументов.

пока что я написал это:

function temp(a, b, c, d){
  document.write(a + b + c + d);
}

function partial(func){
  var arr = new Array();
  for (var i = 0; i<arguments.length; i++){
    arr.push(arguments[i+1]);
  }

  var tf = function(){f.apply(this, arr.concat(func.arguments))}
  console.log(2);
  return tf;
}

var ff = partial(temp, 44, 55);
ff(20, 30); 

но он пишет «Нан» в документе. Мне нужно получить доступ к аргументам функции 'ff' при вызове, но я понятия не имею, как это сделать. Не могли бы вы, ребята, помочь мне решить это?


person Alireza Farahani    schedule 21.11.2013    source источник
comment
Это называется каррингом.   -  person Mathletics    schedule 22.11.2013
comment
Ну, это похоже на каррирование, но, строго говоря, отличается, потому что JavaScript не является языком ленивых вычислений. (Я не уверен на 100%, кто отвечает за терминологию; я понимаю разницу, но я не знаю, кого волнует, как этот термин используется :)   -  person Pointy    schedule 22.11.2013


Ответы (2)


Там было много ненужного тестового кода, который я почистил. Насколько я понимаю, приведенный ниже код и эта демонстрация делают то, что вам нужно.

function temp(a, b, c, d){
  console.log(a + b + c + d);
}

function partial(f){
    var defaultArgs = Array.prototype.slice.call(arguments, 1);
    var that = this;

    var tf = function(){
        f.apply(that, defaultArgs.concat(Array.prototype.slice.call(arguments)));
    }
    return tf;
}

var ff = partial(temp, 44, 55);
ff(20, 30);

// console output: 149
person Asad Saeeduddin    schedule 21.11.2013
comment
@alireza Я одновременно преобразовываю объект arguments в массив и исключаю из него первый элемент. С точки зрения исходного кода это будет эквивалентно вызову arr.slice(1), который извлечет все arr, начиная со второго элемента. - person Asad Saeeduddin; 22.11.2013

Вы можете сделать это с .bind()

function partial(f, x, y) {
  return f.bind(this, x, y);
}
person Pointy    schedule 21.11.2013
comment
+1, не знал об этом. Являются ли связанные функции просто обычными функциями с другой логикой или они каким-то образом отличаются друг от друга? - person Asad Saeeduddin; 22.11.2013
comment
Это обычные функции, но они построены особым образом. В большинстве случаев это не так уж сильно отличается от других ответов здесь. Подробности см. на странице MDN. - person Pointy; 22.11.2013