Ваш путь к классу нарушен (что является общей проблемой very в мире Java).
В зависимости от того, как вы запускаете свое приложение, вам нужно пересмотреть аргумент в -cp
, запись в Class-Path в файле MANIFEST.MF или на вашем диске.
ES2015
В ES2015 параметр деструктурирования параметра может использоваться для имитации именованных параметров. Это потребует, чтобы вызывающий передал объект, но вы можете избежать всех проверок внутри функции, если вы также используете параметры по умолчанию:
myFunction({ param1 : 70, param2 : 175});
function myFunction({param1, param2}={}){
// ...
}
ES5
Там это способ приблизиться к тому, что вы хотите, но он основан на выходе Function.prototype.toString
[ES5] , который зависит от реализации в некоторой степени, поэтому он не может быть совместим с несколькими браузерами .
Идея состоит в том, чтобы проанализировать имена параметров из строкового представления функции, чтобы вы могли ассоциировать свойства объекта с соответствующим параметром.
Затем вызов функции мог выглядят как
func(a, b, {someArg: ..., someOtherArg: ...});
, где a
и b
являются позиционными аргументами, а последний аргумент - объектом с именованными аргументами.
Например:
var parameterfy = (function() {
var pattern = /function[^(]*\(([^)]*)\)/;
return function(func) {
// fails horribly for parameterless functions ;)
var args = func.toString().match(pattern)[1].split(/,\s*/);
return function() {
var named_params = arguments[arguments.length - 1];
if (typeof named_params === 'object') {
var params = [].slice.call(arguments, 0, -1);
if (params.length < args.length) {
for (var i = params.length, l = args.length; i < l; i++) {
params.push(named_params[args[i]]);
}
return func.apply(this, params);
}
}
return func.apply(null, arguments);
};
};
}());
Который вы бы использовали как:
var foo = parameterfy(function(a, b, c) {
console.log('a is ' + a, ' | b is ' + b, ' | c is ' + c);
});
foo(1, 2, 3); // a is 1 | b is 2 | c is 3
foo(1, {b:2, c:3}); // a is 1 | b is 2 | c is 3
foo(1, {c:3}); // a is 1 | b is undefined | c is 3
foo({a: 1, c:3}); // a is 1 | b is undefined | c is 3
Есть некоторые недостатки этого подхода (вы были предупреждены!):
undefined
(это отличается от отсутствия значения вообще). Это означает, что вы не можете использовать arguments.length
для проверки того, сколько аргументов было передано. Вместо функции, создающей оболочку, вы также можете иметь функцию, которая принимает функцию и различные значения в качестве аргументов, например
call(func, a, b, {posArg: ... });
, или даже расширить Function.prototype
, чтобы вы могли:
foo.execute(a, b, {posArg: ...});
Есть другой способ. Если вы передаете объект по ссылке, свойства этого объекта будут отображаться в локальной области функции. Я знаю, что это работает для Safari (не проверял другие браузеры), и я не знаю, имеет ли эта функция имя, но приведенный ниже пример иллюстрирует его использование.
Хотя на практике я не думаю что это предлагает любую функциональную ценность за пределами техники, которую вы уже используете, это немного чище семантически. И по-прежнему требуется передать ссылку на объект или литерал объекта.
function sum({ a:a, b:b}) {
console.log(a+'+'+b);
if(a==undefined) a=0;
if(b==undefined) b=0;
return (a+b);
}
// will work (returns 9 and 3 respectively)
console.log(sum({a:4,b:5}));
console.log(sum({a:3}));
// will not work (returns 0)
console.log(sum(4,5));
console.log(sum(4));
Если вы хотите дать понять, что собой представляет каждый из параметров, а не просто вызвать
someFunction(70, 115);
, то почему бы не сделать следующий
var width = 70, height = 115;
someFunction(width, height);
уверен, это дополнительная строка кода, но она выигрывает на удобочитаемости.
someFunction(height: 115);
, но если вы напишете someFunction(height);
, вы фактически устанавливаете ширину.
– Francisco Presencia
30 April 2015 в 06:51
Trying Node-6.4.0 (process.versions.v8 = '5.0.71.60') и Node Chakracore-v7.0.0-pre8, а затем Chrome-52 (V8 = 5.2.361.49), я заметил, что named параметры реализованы почти , но этот порядок все еще имеет приоритет. Я не могу найти то, что говорит стандарт ECMA.
>function f(a=1, b=2){ console.log(`a=${a} + b=${b} = ${a+b}`) }
> f()
a=1 + b=2 = 3
> f(a=5)
a=5 + b=2 = 7
> f(a=7, b=10)
a=7 + b=10 = 17
Но требуется заказ! Является ли это стандартным поведением?
> f(b=10)
a=10 + b=2 = 12
b=10
является 10
, и это то, что передается функции. f(bla=10)
также будет работать (он назначает 10 переменной bla
и после этого передает значение функции).
– Matthias Kestenholz
17 November 2016 в 14:24
Этот вопрос был моим любимым человеком в течение некоторого времени. Я опытный программист со многими языками под моим поясом. Один из моих любимых языков, которым я имел удовольствие использовать Python. Python поддерживает именованные параметры без каких-либо обманщиков .... Поскольку я начал использовать Python (некоторое время назад), все стало проще. Я считаю, что каждый язык должен поддерживать именованные параметры, но это не так.
Многие люди говорят, что просто используют трюк «Пропустить объект», чтобы вы назвали параметры.
/**
* My Function
*
* @param {Object} arg1 Named arguments
*/
function myFunc(arg1) { }
myFunc({ param1 : 70, param2 : 175});
И это отлично работает, за исключением того, что ..... когда дело доходит до большинства IDE, многие из нас разработчики полагаются на подсказки типа / аргумента в нашей среде IDE. Я лично использую PHP Storm (наряду с другими IDE JetBrains, такими как PyCharm для python и AppCode для Objective C)
И самая большая проблема с использованием трюка «Передача объекта» заключается в том, что когда вы вызываете функцию, IDE дает вам однотипный намек и все ... Как мы должны знать, какие параметры и типы должны входить в объект arg1?
[/g0]
Итак ... трюк «Пропустить объект» не работает для меня ... Это на самом деле вызывает больше головных болей, когда приходится смотреть на док-блок каждой функции, прежде чем я узнаю, какие параметры ожидает функция. Конечно, это отлично подходит, когда вы поддерживаете существующий код, но это ужасно для написания нового кода.
Ну, это тот метод, который я использую ... Теперь могут быть некоторые проблемы с ним, и некоторые разработчики могут скажите мне, что я делаю это неправильно, и у меня есть открытый ум, когда дело доходит до этих вещей ... Я всегда готов смотреть на лучшие способы решения задачи ... Итак, если есть проблема с этой техникой , то комментарии приветствуются.
/**
* My Function
*
* @param {string} arg1 Argument 1
* @param {string} arg2 Argument 2
*/
function myFunc(arg1, arg2) { }
var arg1, arg2;
myFunc(arg1='Param1', arg2='Param2');
Таким образом, у меня есть лучшее из обоих миров ... новый код легко писать, так как моя IDE дает мне все правильные подсказки аргументов ... И, пока поддерживая код позже, я могу сразу увидеть не только значение, переданное функции, но и имя аргумента. Единственный недостаток, который я вижу, - объявлять ваши имена аргументов как локальные переменные, чтобы не загрязнять глобальное пространство имен. Конечно, это немного лишний набор, но тривиальный по сравнению с временем, требуемым для поиска докблоков при написании нового кода или сохранении существующего кода.
[/g1]
myFunc(/*arg1*/ 'Param1', /*arg2*/ 'Param2');
лучше, чем myFunc(arg1='Param1', arg2='Param2');
, потому что у него нет шансов обмануть читателя, чем происходят какие-либо фактические именованные аргументы
– Eric
21 September 2016 в 09:24
Нет - объектный подход - это ответ JavaScript на это. Нет проблем с этим, если ваша функция ожидает объект, а не отдельные параметры.
Другой способ - использовать атрибуты подходящего объекта, например. например:
function plus(a,b) { return a+b; };
Plus = { a: function(x) { return { b: function(y) { return plus(x,y) }}},
b: function(y) { return { a: function(x) { return plus(x,y) }}}};
sum = Plus.a(3).b(5);
Конечно, для этого составленного примера это несколько бессмысленно. Но в тех случаях, когда функция выглядит как
do_something(some_connection_handle, some_context_parameter, some_value)
, она может оказаться более полезной. Это также можно сочетать с идеей «parameterfy», чтобы создать такой объект из существующей функции в общем виде. То есть для каждого параметра он создавал бы элемент, который может оценивать частичную оценочную версию функции.
Эта идея, конечно, связана с Schönfinkeling aka Currying.
Function.prototype
.. Я надеялся, что кто-то пойдет в этом направлении. – Robin Maben 3 August 2012 в 15:58Object.defineProperty
и установитьenumerable
наfalse
). Всегда нужно быть осторожным при расширении собственных объектов. Весь подход немного взломан, поэтому я не ожидал, что он будет работать сейчас и навсегда;) – Felix Kling 3 August 2012 в 16:03