JavaScript: клонировать функцию - PullRequest
96 голосов
/ 02 декабря 2009

Какой самый быстрый способ клонировать функцию в JavaScript (с или без ее свойств)?

На ум приходят два варианта: eval(func.toString()) и function() { return func.apply(..) }. Но я беспокоюсь о производительности eval, и оборачивание ухудшит стек и, вероятно, ухудшит производительность, если его применить много раз или применить к уже упакованному.

new Function(args, body) выглядит хорошо, но как именно я могу надежно разделить существующую функцию на аргументы и тело без JS-парсера в JS?

Заранее спасибо.

Обновление: То, что я имею в виду, это умение

var funcB = funcA.clone(); // where clone() is my extension
funcB.newField = {...};    // without affecting funcA

Ответы [ 12 ]

0 голосов
/ 05 марта 2019

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

Сделайте это, создав функцию создания функции:

function createFunction(param1, param2) {
   function doSomething() {
      console.log('in the function!');
   }
   // Assign properties to `doSomething` if desired, perhaps based
   // on the arguments passed into `param1` and `param2`. Or,
   // even return a different function from among a group of them.
   return doSomething;
};

let a = createFunction();
a.something = 1;
let b = createFunction();
b.something = 2; // does not overwrite a.something
console.log(a.something);
a();
b();

Это не совсем то, что вы обрисовали в общих чертах, однако это зависит от того, как вы хотите использовать функцию, которую вы хотите клонировать. Это также использует больше памяти, потому что фактически создает несколько копий функции, один раз за вызов. Тем не менее, этот метод может решить проблему использования некоторых людей без необходимости сложной clone функции.

0 голосов
/ 25 июля 2018
function cloneFunction(Func, ...args) {
  function newThat(...args2) {
    return new Func(...args2);
  }
  function clone() {
    if (this instanceof clone) {
      return newThat(...args);
    }
    return Func.apply(this, args);
  }
  for (const key in Func) {
    if (Func.hasOwnProperty(key)) {
      clone[key] = Func[key];
    }
  }
  Object.defineProperty(clone, 'name', { value: Func.name, configurable: true })
  return clone
};

function myFunction() {
  console.log('Called Function')
}

myFunction.value = 'something';

const newFunction = cloneFunction(myFunction);

newFunction.another = 'somethingelse';

console.log('Equal? ', newFunction === myFunction);
console.log('Names: ', myFunction.name, newFunction.name);
console.log(myFunction);
console.log(newFunction);
console.log('InstanceOf? ', newFunction instanceof myFunction);

myFunction();
newFunction();

Хотя я бы никогда не рекомендовал использовать это, я подумал, что будет интересной небольшой задачей найти более точный клон, взяв некоторые из практик, которые кажутся лучшими, и немного исправив их. Вот результат логов:

Equal?  false
Names:  myFunction myFunction
{ [Function: myFunction] value: 'something' }
{ [Function: myFunction] value: 'something', another: 'somethingelse' }
InstanceOf?  false
Called Function
Called Function
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...