Вопрос

Общая работа в JavaScript - заменить метод объекта с новым, пока все еще вызывает оригинальный метод.Это часто делается подобным:

var originalMethod = obj.method;
obj.method = function(arg) {
    // call original method
    originalMethod.call(this, arg);
    // do my stuff new stuff
}
.

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

function addXyzMethod1(fn) {
    if (obj.method) {
        var previousMethod = obj.method;
        obj.method = function(value) {
            value = previousMethod.call(this, value);
            return fn.call(this, value);
        };
    } else {
        obj.method = fn;
    }
}

function addXyzMethod2(fn) {
    if (obj._methodList) {
        obj._methodList.push(fn);
    } else if (obj.method) {
        obj._methodList = [obj.method, fn];
        obj.method = function(value) {
            for (var i = 0, n = obj._methodList.length; i < n; i++) {
                value = obj._methodList[i].call(this, value);
            }
            return value;
        };
    } else {
        obj.method = fn;
    }
}
.

На данный момент я не могу решить, какой метод использовать, так как я чувствую, что компромиссы каждая даже даже.Итак, мой вопрос здесь: какой из этих методов лучше (более естественный или принятый или быстрее) или есть другой метод, который улучшается на обоих этих?

Это было полезно?

Решение

Этот вопрос вполне похоже, или, по крайней мере, сводится к аналогичному вопросу здесь: https://stackoverflow.com/questions/660337 / a>

Чтение любимого ответа там, я бы порекомендовал вам придерживаться addyyzmethod1 , если вы знаете, что вам не нужно перезаписать функцию так часто, чтобы вы работали опасности переполнения стека.

Если вы хотите альтернативное решение (что было бы желательно, на мой взгляд), лучше понять то, что вы пытаетесь сделать именно, было бы полезным. Я не требовал этой техники в течение длительного времени и от моего опыта, это плохая практика в большинстве случаев. Есть дизайн паттерс, которые помогут вам избежать этой ситуации. Например. Используйте композицию. Имейте объект, представляющий собой набор функций (может быть простой массивом функций) и ввести что один в свой объект через его конструктор и хранить его в качестве члена. Затем используйте его в этом методе, который вы изначально хотели заменить. Коллекция, которую вы вводили, вы все равно можете добавить и удалять функции из него. Это было бы вроде похоже на ваш addy-dyzmethod2 , не имея эту глобальную функцию UTIL и без необходимости перезаписать оригинальный метод вашего объекта.

Другие советы

What you are trying to do is a JavaScript version of call super, which is described as a code smell by Martin Fowler.

I would suggest instead that you either

  1. Contain the "super" object instead of inheriting from it.
  2. Use template method, such as below

    templateMethod = function () {
         baseMethod();
         if (overrideMethod) {
              overrideMethod();
         }
    };
    

Other objects would call templateMethod. The overrideMethod is where child objects would have their code.

Лицензировано под: CC-BY-SA с атрибуция
scroll top