Пишу библиотеку для работы с классами ES5. Не знаю, как задать имя функции через аргумент метода.
function Classes() {
this.createClass = function(className, keys) {
this[className] = function(...values) { // здесь как-то надо указать className в качестве имени функции
keys.map(key => this[key] = values[keys.indexOf(key)]);
};
return this;
};
}
let classes = new Classes();
classes.createClass("Test", ["a", "b"]);
let test = new classes.Test(1, 2);
console.log(test); // (anonymous function) {a: 1, b: 2} вместо Test {a: 1, b: 2}
Нашел подходящий способ с использованием new Function(), однако не могу в нем разобраться:
function renameFunction(name, fn) {
return (new Function(`return function (call) { return function ${name} () { return call(this, arguments) }; };`)())(Function.apply.bind(fn)); // здесь какая-то магия со сменой контекста
};
let Book = renameFunction("Book", function (title) {
this.title = title;
});
let book = new Book("Cookbook");
console.log(book);
Автор примера выше лихо завернул, можно проще:
function rename(name, prop) {
return new Function(`return function ${name} (val) {
this.${prop} = val; // сначала писал this[${prop}], но это не работало
}`);
}
let Test = rename("Test", "type")();
let test = new Test("js");
console.log(test); // Test {type: "js"}