Каков наилучший способ (ов) поддельной перегрузки функций в Javascript?
Я знаю, что невозможно перегрузить функции в Javascript, как в других языках. Если мне нужна функция с двумя применениями foo(x)
и foo(x,y,z)
что является лучшим / предпочтительным способом:
- Использование разных имен в первую очередь
- Используя необязательные аргументы, такие как
y = y || 'default'
- Используя количество аргументов
- Проверка типов аргументов
- Или как?
javascript
overloading
hamdiakoguz
источник
источник
Ответы:
Лучший способ сделать перегрузку функций параметрами - не проверять длину аргумента или типы; проверка типов просто сделает ваш код медленным, и вы получите удовольствие от массивов, нулей, объектов и т. д.
То, что делают большинство разработчиков, - это использовать объект как последний аргумент своих методов. Этот объект может содержать что угодно.
Тогда вы можете справиться с этим так, как хотите в своем методе. [Переключение, если-еще, и т. Д.]
источник
if(opts['test']) //if test param exists, do something.. if(opts['bar']) //if bar param exists, do something
arguments.length
не рекомендуется? Кроме того, я был здесь раньше и читал, что делают большинство разработчиков ... , но я уверен, что это единственное место, где я видел, что сделал. Этот метод также портит синтаксическую сладость наличия «перегрузок»!Я часто делаю это:
C #:
Эквивалент JavaScript:
Этот конкретный пример на самом деле более элегантен в JavaScript, чем в C #. Параметры, которые не указаны, являются «неопределенными» в javascript, что приводит к значению false в операторе if. Однако определение функции не передает информацию о том, что p2 и p3 являются необязательными. Если вам нужно много перегрузок, jQuery решил использовать объект в качестве параметра, например, jQuery.ajax (options). Я согласен с ними, что это наиболее мощный и четко документируемый подход к перегрузке, но мне редко требуется более одного или двух быстрых необязательных параметров.
РЕДАКТИРОВАТЬ: изменил тест IF в соответствии с предложением Яна
источник
undefined
в JS, нетnull
. Лучше всего никогда не устанавливать ничегоundefined
, поэтому это не должно быть проблемой, пока вы меняете тестp2 === undefined
.false
последний аргумент, он не будет объединен"false"
до конца, потому чтоif(p3)
не будет переходить .typeof p2 === "undefined"
, вероятно, противоположны тому, что вы ожидаете в случае с вашим примером, я думаю,typeof p2 !== "undefined"
это то, что вы хотели. Кроме того, могу ли я предположить, что он должен объединять строку, число и логическое значение, которое вы на самом деле делаетеp2 === "number"; p3 === "boolean"
===
и!==
? Почему бы просто не использовать==
и!=
?В JavaScript нет реальной перегрузки функций, поскольку она позволяет передавать любое количество параметров любого типа. Вы должны проверить внутри функции, сколько аргументов было передано и какого они типа.
источник
Правильный ответ: В JAVASCRIPT НЕТ ПЕРЕГРУЗКИ.
Проверка / переключение внутри функции не является ПЕРЕГРУЗКОЙ.
Концепция перегрузки: в некоторых языках программирования перегрузка функций или перегрузка методов - это возможность создавать несколько методов с одинаковыми именами в разных реализациях. Вызовы перегруженной функции будут запускать конкретную реализацию этой функции, соответствующую контексту вызова, позволяя одному вызову функции выполнять различные задачи в зависимости от контекста.
Например, doTask () и doTask (объект O) являются перегруженными методами. Чтобы вызвать последнее, объект должен быть передан в качестве параметра, тогда как первый не требует параметра и вызывается с пустым полем параметра. Распространенной ошибкой может быть присвоение объекту значения по умолчанию во втором методе, что приведет к неоднозначной ошибке вызова, так как компилятор не будет знать, какой из двух методов использовать.
https://en.wikipedia.org/wiki/Function_overloading
Все предлагаемые реализации великолепны, но, по правде говоря, для JavaScript нет нативной реализации.
источник
Есть два способа лучше подойти к этому:
Передайте словарь (ассоциативный массив), если вы хотите оставить большую гибкость
Возьмите объект в качестве аргумента и используйте наследование на основе прототипа, чтобы добавить гибкость.
источник
Вот подход, который допускает перегрузку реальных методов с использованием типов параметров, показанных ниже:
Изменить (2018) : с тех пор, как это было написано в 2011 году, скорость прямых вызовов методов значительно возросла, а скорость перегруженных методов - нет.
Это не тот подход, который я бы порекомендовал, но стоит подумать над тем, как решить эти типы проблем.
Вот эталон различных подходов - https://jsperf.com/function-overloading . Это показывает, что перегрузка функций (с учетом типов) может быть примерно в 13 раз медленнее в Google Chrome V8 с 16.0 (бета) .
Наряду с передачей объекта (то есть
{x: 0, y: 0}
) можно также использовать подход C, когда это уместно, называя методы соответствующим образом. Например, Vector.AddVector (vector), Vector.AddIntegers (x, y, z, ...) и Vector.AddArray (integerArray). Вы можете посмотреть библиотеки C, такие как OpenGL, для вдохновения в именовании.Изменить : я добавил тест для прохождения объекта и тестирования для объекта с использованием обоих
'param' in arg
иarg.hasOwnProperty('param')
, и перегрузка функции намного быстрее, чем передача объекта и проверка свойств (по крайней мере, в этом тесте).С точки зрения дизайна перегрузка функции допустима или логична только в том случае, если перегруженные параметры соответствуют одному и тому же действию. Таким образом, само собой разумеется, что должен быть базовый метод, который касается только конкретных деталей, в противном случае это может указывать на неправильный выбор дизайна. Таким образом, можно также разрешить использование перегрузки функций путем преобразования данных в соответствующий объект. Конечно, нужно учитывать масштаб проблемы, поскольку нет необходимости создавать сложные дизайны, если вы хотите просто напечатать имя, но для разработки каркасов и библиотек такая мысль оправдана.
Мой пример взят из реализации Rectangle - отсюда и упоминание Dimension and Point. Возможно, Rectangle может добавить
GetRectangle()
метод кDimension
иPoint
прототипу, и тогда проблема перегрузки функции будет решена. А как насчет примитивов? Ну, у нас есть длина аргумента, которая теперь является допустимым тестом, поскольку у объектов естьGetRectangle()
метод.источник
Лучший способ действительно зависит от функции и аргументов. Каждый из ваших вариантов - хорошая идея в разных ситуациях. Обычно я пробую их в следующем порядке, пока один из них не сработает:
Использование необязательных аргументов, таких как y = y || 'дефолт'. Это удобно, если вы можете сделать это, но это не всегда может работать практически, например, когда 0 / null / undefined будет допустимым аргументом.
Используя количество аргументов. Похож на последний вариант, но может работать, когда # 1 не работает.
Проверка типов аргументов. Это может работать в некоторых случаях, когда количество аргументов одинаково. Если вы не можете точно определить типы, вам может потребоваться использовать разные имена.
Использование разных имен в первую очередь. Вам может потребоваться сделать это, если другие опции не будут работать, не будут практичными или для соответствия другим связанным функциям.
источник
Проблема в том, что JavaScript НЕ поддерживает перегрузку методов. Таким образом, если он видит / анализирует две или более функций с одинаковыми именами, он просто учитывает последнюю определенную функцию и перезаписывает предыдущие.
Один из способов, который я считаю подходящим для большинства случаев, заключается в следующем:
Допустим, у вас есть метод
Вместо перегрузки метода, который невозможен в javascript, вы можете определить новый метод
а затем измените первую функцию следующим образом -
Если у вас много таких перегруженных методов, рассмотрите возможность использования
switch
не толькоif-else
операторов.( подробнее )
PS: выше ссылка идет на мой личный блог, который имеет дополнительные подробности.
источник
Я не уверен в лучшей практике, но вот как я это делаю:
источник
Я только что попробовал это, может быть, это соответствует вашим потребностям. В зависимости от количества аргументов вы можете получить доступ к другой функции. Вы инициализируете его при первом вызове. И карта функций скрыта в закрытии.
Попробуй это.
источник
Поскольку в JavaScript нет функции перегрузки функции, можно использовать объект. Если есть один или два обязательных аргумента, лучше держать их отдельно от объекта параметров. Вот пример того, как использовать объект параметров и заполненные значения до значения по умолчанию в случае, если значение не было передано в объекте параметров.
вот пример того, как использовать параметры объекта
источник
Нет способа перегрузить функцию в javascript. Итак, я рекомендую использовать
typeof()
метод, а не несколько функций, чтобы имитировать перегрузку.Удачи!
источник
var type = typeof param; if (type === 'string') ...
ВВЕДЕНИЕ
Пока чтение стольких ответов вызовет головную боль. Любой, кто пытается узнать эту концепцию, должен знать следующие предварительные условия .
Function overloading Definition
,Function Length property
,Function argument property
Function overloading
в простейшем виде означает, что функция выполняет различные задачи на основе количества аргументов, которые ей передаются. В частности, TASK1, TASK2 и TASK3 выделены ниже и выполняются на основе количестваarguments
передаваемых одной и той же функцииfooYo
.ПРИМЕЧАНИЕ. - JS не обеспечивает встроенную возможность перегрузки функций.
альтернатива
Джон Э Ресиг (создатель JS) указал на альтернативу, которая использует вышеуказанные предпосылки для достижения возможности перегрузки функций.
В приведенном ниже коде используется простой, но наивный подход с помощью оператора
if-else
илиswitch
.argument-length
свойство.Другая техника гораздо более чистая и динамичная. Изюминкой этой техники является
addMethod
общая функция.мы определяем функцию,
addMethod
которая используется для добавления различных функций к объекту с одинаковым именем, но разными функциями .ниже
addMethod
функция принимает три параметра имени объекта, имяobject
функцииname
и функцию, которую мы хотим вызватьfn
.addMethod
определенияvar old
хранится ссылка на предыдущееfunction
, хранящееся с помощью замыкания - защитного пузыря.addMethod
добавляются три функции, которые при вызове используютninja.whatever(x)
с числом аргументов,x
которое может быть любым, то есть либо пустым, либо одним или несколькими, вызывает различные функции, как определено при использованииaddMethod
функции.источник
Другой способ сделать это - использовать специальную переменную: arguments , это реализация:
так что вы можете изменить этот код:
источник
Проверь это. Это очень круто. http://ejohn.org/blog/javascript-method-overloading/ Уловка Javascript, позволяющая вам выполнять такие звонки:
источник
Func(new Point())
иFunc(new Rectangle())
буду выполнять разные функции. Но я должен отметить, что это грязный хак, поскольку перегрузка метода действительно является задачей времени компиляции, а не времени выполнения.Перегрузка функций в Javascript:
Перегрузка функций - это способность языка программирования создавать несколько функций с одинаковыми именами в разных реализациях. когда вызывается перегруженная функция, она запускает функцию конкретной реализации этой функции, соответствующую контексту вызова. Этот контекст обычно является количеством аргументов, которые он получает, и он позволяет одному вызову функции вести себя по-разному в зависимости от контекста.
Javascript не имеет встроенной функции перегрузки. Однако такое поведение можно эмулировать разными способами. Вот удобный простой:
В тех случаях, когда вы не знаете, сколько аргументов вы получите, вы можете использовать оператор rest, который состоит из трех точек
...
. Он преобразует оставшуюся часть аргументов в массив. Остерегайтесь совместимости браузера, хотя. Вот пример:источник
Поскольку этот пост уже содержит много разных решений, я подумал, что выложу еще одно.
это можно использовать как показано ниже:
Это решение не идеально, но я только хочу продемонстрировать, как это можно сделать.
источник
Вы можете использовать «addMethod» от Джона Резига. С помощью этого метода вы можете «перегружать» методы на основе количества аргументов.
Я также создал альтернативу этому методу, который использует кэширование для хранения изменений функции. Различия описаны здесь
источник
Шаблон пересылки => наилучшая практика по перегрузке JS
Перейдем к другой функции, имя которой построено из 3-го и 4-го пунктов:
Заявка на ваше дело:
Другой сложный образец:
источник
Перегрузка функций через динамический полиморфизм в 100 строках JS
Это от большей части кода , который включает в себя
isFn
,isArr
и т.д. функции проверки типов. Версия VanillaJS, приведенная ниже, была переработана для удаления всех внешних зависимостей, однако вам придется определить собственные функции проверки типов для использования в.add()
вызовах.Примечание. Это самореализуемая функция (поэтому мы можем иметь закрытое / закрытое пространство видимости), следовательно, присваивание
window.overload
вместоfunction overload() {...}
.Применение:
Вызывающая сторона определяет свои перегруженные функции, назначая переменную для возврата
overload()
. Благодаря сцеплению дополнительные перегрузки могут быть определены последовательно:Единственный необязательный аргумент, который
overload()
определяет функцию «по умолчанию» для вызова, если подпись не может быть идентифицирована. Аргументы.add()
:fn
:function
определение перегрузки;a_vArgumentTests
:Array
Изfunction
й определяющих тестов для запуска наarguments
. Каждыйfunction
принимает один аргумент и возвращаетtrue
твой в зависимости от того, является ли аргумент действительным;sAlias
(Необязательно):string
определение псевдонима для прямого доступа к функции перегрузки (fn
), напримерmyOverloadedFn.noArgs()
, вызовет эту функцию напрямую, избегая тестов аргументов на динамический полиморфизм.Эта реализация на самом деле допускает не только традиционные перегрузки функций в качестве второго
a_vArgumentTests
аргумента.add()
практике определяет пользовательские типы. Таким образом, вы можете задавать аргументы не только по типу, но и по диапазонам, значениям или коллекциям значений!Если вы посмотрите на 145 строк кода,
overload()
вы увидите, что каждая подпись классифицируется по количествуarguments
переданных ей. Это сделано для того, чтобы мы ограничивали количество тестов, которые мы проводим. Я также отслеживаю количество звонков. С некоторым дополнительным кодом, массивы перегруженных функций могут быть пересортированы так, чтобы сначала тестировались более часто вызываемые функции, снова добавляя некоторую меру повышения производительности.Теперь есть несколько предостережений ... Поскольку Javascript свободно набирается, вам нужно быть осторожным с тем,
vArgumentTests
чтоinteger
можно проверить как afloat
и т. Д.Версия JSCompress.com (1114 байтов, 744 байта в сжатом виде):
источник
Теперь вы можете выполнять перегрузку функций в ECMAScript 2018 без полизаполнений, проверки длины / типа переменной и т. Д., Просто используйте синтаксис расширения .
Что такое распространенный синтаксис?
Примечание: синтаксис распространения в объектных литералах не работает в Edge и IE, и это экспериментальная функция. увидеть совместимость браузера
источник
Нечто подобное можно сделать для перегрузки функций.
Источник
источник
Это старый вопрос, но мне кажется, что нужна еще одна запись (хотя я сомневаюсь, что кто-нибудь прочтет ее). Использование выражений с немедленным вызовом функций (IIFE) может использоваться в сочетании с замыканиями и встроенными функциями для обеспечения перегрузки функций. Рассмотрим следующий (надуманный) пример:
Короче говоря, использование IIFE создает локальную область, что позволяет нам определять приватную переменную
old
для хранения ссылки на первоначальное определение функцииfoo
. Затем эта функция возвращает встроенную функцию,newFoo
которая регистрирует содержимое обоих двух аргументов, если ей передано ровно два аргумента,a
и /b
или вызываетold
функцию ifarguments.length !== 2
. Этот шаблон может повторяться любое количество раз, чтобы наделить одну переменную несколькими различными функциональными определениями.источник
Я хотел бы поделиться полезным примером перегруженного подхода.
Использование: Очистить (); // очищает весь документ
Clear (myDiv); // Очищает панель, на которую ссылается myDiv
источник
JavaScript - это нетипизированный язык, и я думаю, что имеет смысл перегружать метод / функцию в отношении количества параметров. Следовательно, я бы рекомендовал проверить, был ли параметр определен:
источник
По состоянию на июль 2017 года, следующая техника была общей. Обратите внимание, что мы также можем выполнять проверку типов внутри функции.
источник
Для вашего случая использования вот как я бы с этим справился
ES6
(так как это уже конец 2017 года):Очевидно, вы можете адаптировать его для работы с любым количеством параметров и просто соответствующим образом изменить свои условные выражения.
источник
в JS нет реальной перегрузки, в любом случае мы все еще можем имитировать перегрузку метода несколькими способами:
Метод № 1: использовать объект
Метод № 2: использовать остальные параметры
Метод № 3: использовать неопределенный
Метод № 4: проверка типа
источник
Хотя параметры по умолчанию не перегружены, это может решить некоторые проблемы, с которыми сталкиваются разработчики в этой области. Вход строго определен порядком, вы не можете изменить порядок, как вы хотите, как при классической перегрузке:
Результаты за (к 2020 году):
Дополнительная информация: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters
источник
Первый вариант действительно заслуживает внимания, потому что я подошел к довольно сложной настройке кода. Итак, мой ответ
С небольшой, но важной подсказкой имена должны отличаться для компьютера, но не для вас. Назовите перегруженные функции, такие как: func, func1, func2.
источник