Что делает MooTools 'Function.prototype.overloadSetter ()? - PullRequest
15 голосов
/ 24 октября 2010

Я просматриваю исходный код MooTools, чтобы попытаться понять его утилиты .implement() и * 1002.

Однако мне трудно понять, что она делает.

Можете ли вы объяснить, как эта функция работает и что она делает?

Ответы [ 2 ]

29 голосов
/ 25 октября 2010

overloadSetter

overloadSetter вместе с overloadGetter представляют собой два метода декоратора функций. Функция overloadSetter используется для преобразования функций, имеющих подпись fn(key, value), в функции, которые могут принимать аргументы объекта, например: fn({key: value}).

Чтобы сделать это, overloadSetter должен обернуть оригинальную функцию. Эта функция-обертка имеет подпись fn(a, b), которая является ярлыком для fn(key, value). Это фактически становится новой перегруженной версией исходной функции.

Первое, что делает эта перегруженная функция, это проверяет, является ли переданный key аргумент (a) строковым типом или нет. Если это не строка, функция предполагает, что мы передаем объект. Таким образом, он перебирает каждую пару ключ-значение в объекте и применяет к нему исходную функцию. С другой стороны, если это строка, она просто применяет функцию к значениям аргументов a и b.

* ** 1023 тысяча двадцать-дв * Пример

Для иллюстрации, скажем, у нас есть следующая функция:

var fnOrig = function(key, value){
    console.log(key + ': ' + value); 
};

var fnOver = fnOrig.overloadSetter();

fnOver('fruit', 'banana');
fnOver({'fruit': 'banana', 'vegetable': 'carrot'});

В первом вызове функция fnOver вызывается с двумя аргументами, ключом и значением. Когда функция проверяет тип значения аргумента a, она увидит, что это строка. Следовательно, он просто вызовет исходную функцию fnOrig: fnOrig.call(this, 'fruit', 'banana'). Наш вывод консоли 'fruit: banana'.

Для второго вызова функция fnOver вызывается с аргументом объекта. Поскольку мы передали объект вместо строки, fnOver будет перебирать членов этого объекта и вызывать функцию fnOrig для каждого из них. Таким образом, fnOrig будет вызываться дважды в этом случае: fnOrig.call(this, 'fruit', 'banana') и fnOrig.call(this, 'vegetable', 'carrot'). Наша консоль выводит 'fruit: banana' и 'vegetable: carrot'.

Дополнительно

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

Другая вещь, код enumerables, который исключает фактическое объявление метода, существует потому, что устраняет проблему с некоторыми браузерами, в которых собственные методы Object не перечисляются в циклах for/in, даже если сам объект реализует его собственная версия.

3 голосов
/ 20 января 2011

Часть, которая заставляла меня некоторое время чесать голову, была

var enumerables = true; for (var i in {toString: 1}) enumerables = null;

часть, которая оказывается тестом на ошибку DontEnum, которую имеют некоторые браузеры. На первый взгляд кажется, что нужно просто установить enumerables на null, но с ошибкой DontEnum toString подавляется (неправильно, потому что prototype.toString объекта имеет флаг DontEnum) и enumerables остается как true.

overloadSetter (или, скорее, результирующая функция) затем должна проверять по одному за семь свойств, на которые влияет ошибка DontEnum, чтобы увидеть, существуют ли они в аргументе объекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...