Теперь я видел 2 метода для определения, был ли аргумент передан функции JavaScript. Мне интересно, если один метод лучше, чем другой, или один просто плохо использовать?
function Test(argument1, argument2) {
if (Test.arguments.length == 1) argument2 = 'blah';
alert(argument2);
}
Test('test');
Или
function Test(argument1, argument2) {
argument2 = argument2 || 'blah';
alert(argument2);
}
Test('test');
Насколько я могу судить, они оба приводят к одному и тому же, но я использовал только первый, который был в производстве.
Другой вариант, упомянутый Томом :
function Test(argument1, argument2) {
if(argument2 === null) {
argument2 = 'blah';
}
alert(argument2);
}
Согласно комментарию Хуана, было бы лучше изменить предложение Тома на:
function Test(argument1, argument2) {
if(argument2 === undefined) {
argument2 = 'blah';
}
alert(argument2);
}
javascript
arguments
Дэррил Хейн
источник
источник
argument2 || 'blah';
приведет к «бла», еслиargument2
естьfalse
(!), А не просто, если оно не определено. Еслиargument2
это логическое значение, иfalse
для него передается функция , эта строка вернет «бла», несмотря наargument2
то, что она определена правильно .argument2
есть0
,''
илиnull
.Ответы:
Есть несколько разных способов проверить, был ли передан аргумент функции. В дополнение к двум из них, которые вы упомянули в своем (оригинальном) вопросе - проверке
arguments.length
или использовании||
оператора для предоставления значений по умолчанию - можно также явно проверить аргументы дляundefined
viaargument2 === undefined
илиtypeof argument2 === 'undefined'
если вы параноик (см. Комментарии).Использование
||
оператора стало стандартной практикой - все крутые дети делают это - но будьте осторожны: Значение по умолчанию будет срабатывать , если аргумент имеет значениеfalse
, что означает , что она может быть на самом делеundefined
,null
,false
,0
,''
(или что - нибудь еще , для которогоBoolean(...)
возвращаетсяfalse
).Таким образом, вопрос заключается в том, когда использовать какую проверку, поскольку все они дают немного разные результаты.
Проверка
arguments.length
демонстрирует «наиболее правильное» поведение, но это может оказаться невозможным, если имеется более одного необязательного аргумента.Следующий критерий
undefined
является «лучшим» - он только «проваливается», если функция явно вызывается соundefined
значением, которое, по всей вероятности, следует обрабатывать так же, как и пропустить аргумент.Использование
||
оператора может инициировать использование значения по умолчанию, даже если указан допустимый аргумент. С другой стороны, его поведение действительно может быть желательным.Подводя итог: используйте его, только если знаете, что делаете!
На мой взгляд, использование
||
- это также путь, если есть более одного необязательного аргумента, и вы не хотите передавать литерал объекта в качестве обходного пути для именованных параметров.Другой хороший способ обеспечить использование значений по умолчанию
arguments.length
возможен, если пролистать метки оператора switch:Это имеет обратную сторону: намерение программиста не является (визуально) очевидным и использует «магические числа»; поэтому возможно ошибки.
источник
Если вы используете jQuery, один вариант, который хорош (особенно для сложных ситуаций), - это использовать метод extends jQuery .
Если вы вызываете функцию, то вот так:
Переменная options тогда будет:
источник
Это один из немногих случаев, когда я нахожу тест:
работает довольно хорошо и несет правильное значение синтаксически.
(С одновременным ограничением, которое я не позволил бы допустимому нулевому значению, для
argument2
которого есть некоторое другое значение; но это было бы действительно запутанным.)РЕДАКТИРОВАТЬ:
Это действительно хороший пример стилистической разницы между свободно типизированными и строго типизированными языками; и стилистический вариант, который Javascript предоставляет в пики.
Мое личное предпочтение (без критики для других предпочтений) - минимализм. Чем меньше должен сказать код, пока я последовательный и лаконичный, тем меньше кто-то другой должен понять, чтобы правильно понять мой смысл.
Одним из следствий этого предпочтения является то, что я не хочу - не считаю это полезным - накапливать кучу тестов на зависимости типов. Вместо этого я пытаюсь сделать так, чтобы код имел в виду то, как он выглядит; и проверять только то, что мне действительно нужно проверить.
Одно из отягчающих обстоятельств, которое я нахожу в коде некоторых других людей, заключается в том, чтобы выяснить, действительно ли они ожидают, в более широком контексте, действительно столкнуться с делами, которые они проверяют. Или, если они пытаются проверить на все возможное, на шанс, что они не предвидят контекст полностью. Это означает, что мне в конечном итоге необходимо полностью выследить их в обоих направлениях, прежде чем я смогу уверенно изменить или изменить что-либо. Я полагаю, что есть хороший шанс, что они могли провести эти различные тесты на месте, потому что они предвидели обстоятельства, в которых они были бы необходимы (и которые обычно не очевидны для меня).
(Я считаю серьезным недостатком то, как эти люди используют динамические языки. Слишком часто люди не хотят отказываться от всех статических тестов и заканчивают тем, что имитируют его.)
Я видел это наиболее ярко при сравнении всеобъемлющего кода ActionScript 3 с элегантным кодом javascript. AS3 может в 3 или 4 раза превышать объем js, и я подозреваю, что надежность, по крайней мере, не лучше, просто из-за количества (3-4X) решений по кодированию, которые были приняты.
Как вы говорите, Shog9, YMMV. : D
источник
Есть существенные различия. Давайте настроим несколько тестовых случаев:
При первом описанном вами методе только второй тест будет использовать значение по умолчанию. Второй метод будет по умолчанию все , кроме первого (как JS будет конвертировать
undefined
,null
,0
и""
в логическое значениеfalse
. И если бы вы использовали метод Тома, только четвертый тест будет использовать по умолчанию!Какой метод вы выберете, действительно зависит от вашего предполагаемого поведения. Если значения, отличные от
undefined
допустимыхargument2
, то вам, вероятно, понадобится некоторое изменение первого; если желательно ненулевое, ненулевое, непустое значение, тогда второй метод идеален - действительно, он часто используется для быстрого исключения из рассмотрения такого широкого диапазона значений.источник
источник
В ES6 (ES2015) вы можете использовать параметры по умолчанию
источник
"default value"
и проверив, действительно ли это значение"default value"
.Извините, я все еще не могу комментировать, поэтому, чтобы ответить на вопрос Тома ... В javascript (undefined! = Null) == false На самом деле эта функция не будет работать с "null", вы должны использовать "undefined"
источник
Почему бы не использовать
!!
оператор? Этот оператор, помещенный перед переменной, превращает ее в логическое значение (если я хорошо понял), поэтому!!undefined
и!!null
(и даже!!NaN
, что может быть довольно интересно) вернетfalse
.Вот пример:
источник
Может быть удобно приблизиться к обнаружению аргумента, вызывая вашу функцию с Объектом дополнительных свойств:
источник
Есть также хитрый способ выяснить, передан ли параметр в функцию или нет . Посмотрите на приведенный ниже пример:
Это означает, что если значение
value
не указано / не передано, установите значение 0.Довольно круто, да!
источник
value
эквивалентноfalse
, установить его на 0.» Это тонкое, но очень важное различие.true
иfalse
являются допустимыми значениями, и вы можете захотеть иметь третье поведение, когда параметр вообще не передается (особенно если функция имеет более одного параметра).Иногда вам также может понадобиться проверить тип, особенно если вы используете функцию как метод получения и установки. Следующий код ES6 (не будет работать в EcmaScript 5 или более ранней версии):
источник
Потому что массивы наследуются от
Object.prototype
. Подумайте, чтобы сделать мир лучше.источник
fnCalledFunction (Param1, Param2, window.YourOptionalParameter)
Если указанная выше функция вызывается из многих мест, и вы уверены, что первые 2 параметра передаются отовсюду, но не уверены в третьем параметре, тогда вы можете использовать окно.
window.param3 будет обрабатывать, если он не определен из метода вызывающего.
источник