Почему я получаю сообщение об отключении эмулятора-5554

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 

DEMO

Есть некоторые недостатки этого подхода (вы были предупреждены!):

  • Если последний аргумент является объектом, он рассматривается как «именованные объекты аргументов»
  • You wil Я всегда получаю столько аргументов, сколько вы определили в функции, но некоторые из них могут иметь значение undefined (это отличается от отсутствия значения вообще). Это означает, что вы не можете использовать arguments.length для проверки того, сколько аргументов было передано.

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

call(func, a, b, {posArg: ... });

, или даже расширить Function.prototype, чтобы вы могли:

foo.execute(a, b, {posArg: ...});

30
задан ChrisWue 4 April 2012 в 19:27
поделиться