Вот быстрый и грязный пример того, как класс может запускать разные версии метода сохранения, в зависимости от того, какую операционную систему он выполняет при использовании getattr()
.
import os
class Log(object):
def __init__(self):
self.os = os.name
def __getattr__(self, name):
""" look for a 'save' attribute, or just
return whatever attribute was specified """
if name == 'save':
try:
# try to dynamically return a save
# method appropriate for the user's system
return getattr(self, self.os)
except:
# bail and try to return
# a default save method
return getattr(self, '_save')
else:
return getattr(self, name)
# each of these methods could have save logic specific to
# the system on which the script is executed
def posix(self): print 'saving on a posix machine'
def nt(self): print 'saving on an nt machine'
def os2(self): print 'saving on an os2 machine'
def ce(self): print 'saving on a ce machine'
def java(self): print 'saving on a java machine'
def riscos(self): print 'saving on a riscos machine'
def _save(self): print 'saving on an unknown operating system'
def which_os(self): print os.name
Теперь давайте использовать этот класс в примере:
logger = Log()
# Now you can do one of two things:
save_func = logger.save
# and execute it, or pass it along
# somewhere else as 1st class:
save_func()
# or you can just call it directly:
logger.save()
# other attributes will hit the else
# statement and still work as expected
logger.which_os()
Если я сейчас правильно понимаю, вы можете использовать Object.values
и Spread Syntax , чтобы выполнить это:
var myFunction = function(param1, param2) {
console.log(param1);
console.log(param2);
}
var functionParameters = {
data1: "test",
data2: "another test"
};
var run = myFunction.bind(null, ...Object.values(functionParameters))
run();
Я бы предположил, что самым простым решением будет просто передать массив ...
var myFunction = function(args) {
args.forEach((i) => console.log(i));
}
var functionParameters = {
1: "test",
2: "another test",
3: "another one"
};
var run = myFunction.bind(null, Object.values(functionParameters)) //Get array of values from the object
run();
Если вы планируете отправлять только определенные значения объекта, как у вас в вашем примере, вы можете использовать Rest Parameters ]:
var myFunction = function(...args) {
args.forEach((i) => console.log(i));
}
var functionParameters = {
data1: "test",
data2: "another test",
data3: "another one"
};
var run = myFunction.bind(null, functionParameters.data1, functionParameters.data2, functionParameters.data3) //Get array of values from the object
run();
//myFunction("This", "function", "will", "now", "take", "unlimited", "parameters");
Вам может понравиться попробовать операцию распространения
function fn(a,b,c){
console.log(a,b,c)
}
, и вы могли бы сделать
const paras = [1,2,3];
const myFun = fn.bind(null, ...paras)
Он выведет 1,2,3
, когда вы вызываете myFun()
Однако он работает только для массива.
Если вы ищете решение для типа сопоставления значений ключа, вам может потребоваться написать функцию клей, которая преобразует значение в массив.
Например, у вас есть тип объекта
const paras = {b:1, a:2, c:3};
, вы можете преобразовать его в массив с помощью
const arrayParas = ['a','b','c'].map(field => paras[field])
И затем вы можете связать свою функцию
const myFun = fn.bind(null, ...arrayParas)
Редактировать: если вы не знаете, как подавать / как получить имя параметра из функции
Js имеет свою toString, которая преобразует функцию в строку, которая содержит входной параметр этой функции.
Но вам нужно убедиться, что имя входных параметров в функции точно совпадает с именами полей в объекте.
// get function parameter name
function getParameterNames(func) {
const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
const ARGUMENT_NAMES = /([^\s,]+)/g;
const fnStr = func.toString().replace(STRIP_COMMENTS, '');
const result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
if (result === null)
result = [];
return result;
}
//
function fn(a, b, c) {
console.log(a, b, c)
}
const paraObjs = {
c: 3,
a: 1,
b: 2
};
const fields = getParameterNames(fn);
const paraArray = fields.map(field => paraObjs[field]);
const myFun = fn.bind(null, ...paraArray)
myFun();
Object.values
в старых средах, которые ее не поддерживают, вы можете найти Polyfill в tc39 / items-objects-values-entries или в es-shims / Object.values репозитории. – Tyler Roper 13 July 2018 в 19:22Object.values
, вы определенно не должны использовать синтаксис распространения, который использует оба текущих ответа. – Tyler Roper 13 July 2018 в 19:28Object.values
(все браузеры, кроме IE), то он не должен также рассматривать использование синтаксиса распространения, поскольку он намного более новый и менее поддерживаемый. – Tyler Roper 13 July 2018 в 19:39