나는 이것을 가지고있다:
this.f = function instance(){};
나는 이것을 갖고 싶다 :
this.f = function ["instance:" + a](){};
나는 이것을 가지고있다:
this.f = function instance(){};
나는 이것을 갖고 싶다 :
this.f = function ["instance:" + a](){};
this["instance" + a] = function() { }
. 그것은 나에게 명확하지 않았습니다.
답변:
다른 사람들이 언급했듯이 이것은 가장 빠르거나 가장 권장되는 솔루션이 아닙니다. 아래 Marcosc의 해결책 은 갈 길입니다.
eval을 사용할 수 있습니다.
var code = "this.f = function " + instance + "() {...}";
eval(code);
eval()
( Function
생성자가 내부에서 수행합니다).
이것은 기본적으로 가장 간단한 수준에서 수행합니다.
"use strict";
var name = "foo";
var func = new Function(
"return function " + name + "(){ alert('sweet!')}"
)();
//call it, to test it
func();
좀 더 멋지게 만들고 싶다면 " JavaScript의 동적 함수 이름 "에 대한 기사를 작성했습니다 .
MDN JavaScript Reference [1]에 명시된대로 Object.defineProperty를 사용할 수 있습니다.
var myName = "myName";
var f = function () { return true; };
Object.defineProperty(f, 'name', {value: myName, writable: false});
function fn()
, fn
원래 이름 인. 기묘한.
최근 엔진에서는 다음을 수행 할 수 있습니다.
function nameFunction(name, body) {
return {[name](...args) {return body(...args)}}[name]
}
const x = nameFunction("wonderful function", (p) => p*2)
console.log(x(9)) // => 18
console.log(x.name) // => "wonderful function"
Object.defineProperty(func, 'name', {value: name})
조금 더 자연스럽고 이해할 수 있다고 생각하기 때문에 내 코드에서 사용하기 시작했습니다 .
{[expr]: val}
is an object initializer (as is as a JSON object) where expr
is some expression; 평가되는 것이 무엇이든 핵심입니다. {myFn (..){..} }
는 {myFn: function myFn(..){..} }
. 참고 function myFn(..) {..}
단지 익명 함수와 같은 표현으로 사용할 수 있습니다 만 myFn
이름을 가질 것이다. 마지막 [name]
은 객체의 멤버에 액세스하는 것입니다 ( obj.key
또는 처럼 obj['key']
). ...
스프레드 연산자입니다. (주요 출처 : developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… )
this
. 예를 들어 obj={x:7,getX(){return this.x}}; obj.getX=nameFunction('name',obj.getX); obj.getX();
작동하지 않습니다. 답변을 편집하고 function nameFunction(name, body) { return {[name](...args) {return body.apply(this, args)}}[name] }
대신 사용할 수 있습니다 !
여기에서 대부분의 제안은 eval, hacky 솔루션 또는 래퍼를 사용하여 차선책이라고 생각합니다. ES2015에서 이름은 변수 및 속성의 구문 위치에서 유추됩니다.
따라서 이것은 잘 작동합니다.
const name = 'myFn';
const fn = {[name]: function() {}}[name];
fn.name // 'myFn'
이름을 추론하기 위해 외부에서 함수를 전달하고 구문 위치로 개조 할 수 없기 때문에 명명 된 함수 팩토리 메서드를 만들려는 유혹에 저항하십시오. 그럼 벌써 너무 늦었어요. 정말로 필요하다면 래퍼를 만들어야합니다. 누군가 여기서 그렇게했지만 그 솔루션은 클래스 (함수이기도 함)에서는 작동하지 않습니다.
설명 된 모든 변형에 대한 훨씬 더 자세한 답변이 여기에 작성되었습니다 : https://stackoverflow.com/a/9479081/633921
구문 은 이름으로 인덱싱 된 function[i](){}
함수 인 속성 값이있는 객체를 의미합니다 .
따라서 .function[]
[i]
{"f:1":function(){}, "f:2":function(){}, "f:A":function(){}, ... } ["f:"+i]
{"f:1":function f1(){}, "f:2":function f2(){}, "f:A":function fA(){}} ["f:"+i]
함수 이름 식별을 유지합니다. 에 대한 아래 참고를 참조하십시오 :
.
그래서,
javascript: alert(
new function(a){
this.f={"instance:1":function(){}, "instance:A":function(){}} ["instance:"+a]
}("A") . toSource()
);
({f:(function () {})})
FireFox에 표시됩니다 .
(이것은 이 솔루션 과 거의 같은 아이디어 입니다. . 단지 일반 객체를 사용하고 더 이상 함수로 창 객체를 직접 채우지 않습니다.)
이 메서드는 환경을 명시 적으로 instance:x
.
javascript: alert(
new function(a){
this.f=eval("instance:"+a+"="+function(){})
}("A") . toSource()
);
alert(eval("instance:A"));
디스플레이
({f:(function () {})})
과
function () {
}
속성 함수가 f
an anonymous function
과 not을 참조 하지만 instance:x
이 방법은 이 솔루션에서 몇 가지 문제를 방지 합니다 .
javascript: alert(
new function(a){
eval("this.f=function instance"+a+"(){}")
}("A") . toSource()
);
alert(instanceA); /* is undefined outside the object context */
표시 만
({f:(function instanceA() {})})
:
는 자바 스크립트를 만듭니다function instance:a(){}
유효하지 않게 .eval
.다음은 반드시 문제가되는 것은 아닙니다.
instanceA
기능은 다음과 같이 직접 사용할 수 없습니다.instanceA()
따라서 원래 문제 컨텍스트와 훨씬 더 일치합니다.
이러한 고려 사항을 감안할 때
this.f = {"instance:1": function instance1(){},
"instance:2": function instance2(){},
"instance:A": function instanceA(){},
"instance:Z": function instanceZ(){}
} [ "instance:" + a ]
OP 예제의 의미와 구문으로 글로벌 컴퓨팅 환경을 최대한 유지합니다.
(name => ({[name]:function(){}})[name])('test')
작동하지만 (name => {var x={}; x[name] = function(){}; return x[name];})('test')
하지 않습니다
가장 많이 득표 한 답변은 이미 정의 된 [String] 함수 본문입니다. 이미 선언 된 함수 이름의 이름을 바꾸는 솔루션을 찾고 있었고 마침내 한 시간 동안 고생 한 후 처리했습니다. 그것:
.toString()
메서드function
와 사이에 새 이름을 추가합니다.(
new Function()
생성자로 새 이름이 바뀐 함수를 만듭니다.function nameAppender(name,fun){
const reg = /^(function)(?:\s*|\s+([A-Za-z0-9_$]+)\s*)(\()/;
return (new Function(`return ${fun.toString().replace(reg,`$1 ${name}$3`)}`))();
}
//WORK FOR ALREADY NAMED FUNCTIONS:
function hello(name){
console.log('hello ' + name);
}
//rename the 'hello' function
var greeting = nameAppender('Greeting', hello);
console.log(greeting); //function Greeting(name){...}
//WORK FOR ANONYMOUS FUNCTIONS:
//give the name for the anonymous function
var count = nameAppender('Count',function(x,y){
this.x = x;
this.y = y;
this.area = x*y;
});
console.log(count); //function Count(x,y){...}
객체의 동적 메서드는 ECMAScript 2015 (ES6)에서 제공하는 Object Literal Extensions를 사용하여 생성 할 수 있습니다.
const postfixes = ['foo', 'bar'];
const mainObj = {};
const makeDynamic = (postfix) => {
const newMethodName = 'instance: ' + postfix;
const tempObj = {
[newMethodName]() {
console.log(`called method ${newMethodName}`);
}
}
Object.assign(mainObj, tempObj);
return mainObj[newMethodName]();
}
const processPostfixes = (postfixes) => {
for (const postfix of postfixes) {
makeDynamic(postfix);
}
};
processPostfixes(postfixes);
console.log(mainObj);
위 코드를 실행 한 결과는 다음과 같습니다.
"called method instance: foo"
"called method instance: bar"
Object {
"instance: bar": [Function anonymous],
"instance: foo": [Function anonymous]
}
o={}; o[name]=(()=>{})
보다는function <<name>>(){}
기존 익명 함수 의 이름을 설정하려면 :
(@Marcosc의 답변에 따라)
var anonymous = function() { return true; }
var name = 'someName';
var strFn = anonymous.toString().replace('function ', 'return function ' + name);
var fn = new Function(strFn)();
console.log(fn()); // —> true
데모 .
참고 :하지 마십시오; /
이를 달성하는 데는 두 가지 방법이 있으며 장단점이 있습니다.
name
속성 정의함수의 불변 name
속성 정의 .
() 全 {}/1/얏호/ :D #GO(@*#%! /*
)name
속성 값 과 일치하지 않을 수 있습니다 .메이킹 라는 이름의 기능 발현 및 평가 와 함께Function
생성자.
name
속성 값 과 일치 합니다.(){}/1//
의 경우 식은 함수 대신 return function (){}/1//() {}
제공 NaN
됩니다.)const demoeval = expr => (new Function(`return ${expr}`))();
// `name` property definition
const method1 = func_name => {
const anon_func = function() {};
Object.defineProperty(anon_func, "name", {value: func_name, writable: false});
return anon_func;
};
const test11 = method1("DEF_PROP"); // No whitespace
console.log("DEF_PROP?", test11.name); // "DEF_PROP"
console.log("DEF_PROP?", demoeval(test11.toString()).name); // ""
const test12 = method1("DEF PROP"); // Whitespace
console.log("DEF PROP?", test12.name); // "DEF PROP"
console.log("DEF PROP?", demoeval(test12.toString()).name); // ""
// Function expression evaluation
const method2 = func_name => demoeval(`function ${func_name}() {}`);
const test21 = method2("EVAL_EXPR"); // No whitespace
console.log("EVAL_EXPR?", test21.name); // "EVAL_EXPR"
console.log("EVAL_EXPR?", demoeval(test21.toString()).name); // "EVAL_EXPR"
const test22 = method2("EVAL EXPR"); // Uncaught SyntaxError: Unexpected identifier
__call
PHP의 함수와 같은 동적 함수를 갖고 싶다면 프록시를 사용할 수 있습니다.
const target = {};
const handler = {
get: function (target, name) {
return (myArg) => {
return new Promise(resolve => setTimeout(() => resolve('some' + myArg), 600))
}
}
};
const proxy = new Proxy(target, handler);
(async function() {
const result = await proxy.foo('string')
console.log('result', result) // 'result somestring' after 600 ms
})()
이와 같은 동적 함수 이름 및 매개 변수를 사용할 수 있습니다.
1) Separate 함수 정의 및 호출
let functionName = "testFunction";
let param = {"param1":1 , "param2":2};
var func = new Function(
"return " + functionName
)();
func(param);
function testFunction(params){
alert(params.param1);
}
2) 동적 기능 코드 정의
let functionName = "testFunction(params)";
let param = {"param1":"1" , "param2":"2"};
let functionBody = "{ alert(params.param1)}";
var func = new Function(
"return function " + functionName + functionBody
)();
func(param);
이 유틸리티 함수는 여러 함수를 하나로 병합합니다 (사용자 지정 이름 사용). 제공된 함수가 특종의 시작과 끝에서 적절하게 "새 줄로 표시"되어야한다는 점만 요구됩니다.
const createFn = function(name, functions, strict=false) {
var cr = `\n`, a = [ 'return function ' + name + '(p) {' ];
for(var i=0, j=functions.length; i<j; i++) {
var str = functions[i].toString();
var s = str.indexOf(cr) + 1;
a.push(str.substr(s, str.lastIndexOf(cr) - s));
}
if(strict == true) {
a.unshift('\"use strict\";' + cr)
}
return new Function(a.join(cr) + cr + '}')();
}
// test
var a = function(p) {
console.log("this is from a");
}
var b = function(p) {
console.log("this is from b");
}
var c = function(p) {
console.log("p == " + p);
}
var abc = createFn('aGreatName', [a,b,c])
console.log(abc) // output: function aGreatName()
abc(123)
// output
this is from a
this is from b
p == 123
Darren의 대답 과 kyernetikos의 대답 을 결합하는 데 더 운이 좋았습니다 .
const nameFunction = function (fn, name) {
return Object.defineProperty(fn, 'name', {value: name, configurable: true});
};
/* __________________________________________________________________________ */
let myFunc = function oldName () {};
console.log(myFunc.name); // oldName
myFunc = nameFunction(myFunc, 'newName');
console.log(myFunc.name); // newName
참고 : Function.name 1에 대한 표준 ES2015 사양과 일치하도록 configurable
설정됩니다.true
이 특히 유사 웹팩에 오류 하는것에 도움 이 하나 .
업데이트 : 나는 이것을 npm 패키지로 게시하려고 생각했지만 sindresorhus의이 패키지 는 똑같은 일을합니다.
이 문제로 많은 어려움을 겪었습니다. @Albin 솔루션은 개발하는 동안 매력적으로 작동했지만 프로덕션으로 변경하면 작동하지 않았습니다. 몇 가지 디버깅 후 필요한 것을 달성하는 방법을 깨달았습니다. 저는 ES6를 CRA (create-react-app)와 함께 사용하고 있습니다. 즉, Webpack에 번들로 제공됩니다.
필요한 기능을 내보내는 파일이 있다고 가정 해 보겠습니다.
myFunctions.js
export function setItem(params) {
// ...
}
export function setUser(params) {
// ...
}
export function setPost(params) {
// ...
}
export function setReply(params) {
// ...
}
그리고 이러한 함수를 다른 곳에서 동적으로 호출해야합니다.
myApiCalls.js
import * as myFunctions from 'path_to/myFunctions';
/* note that myFunctions is imported as an array,
* which means its elements can be easily accessed
* using an index. You can console.log(myFunctions).
*/
function accessMyFunctions(res) {
// lets say it receives an API response
if (res.status === 200 && res.data) {
const { data } = res;
// I want to read all properties in data object and
// call a function based on properties names.
for (const key in data) {
if (data.hasOwnProperty(key)) {
// you can skip some properties that are usually embedded in
// a normal response
if (key !== 'success' && key !== 'msg') {
// I'm using a function to capitalize the key, which is
// used to dynamically create the function's name I need.
// Note that it does not create the function, it's just a
// way to access the desired index on myFunctions array.
const name = `set${capitalizeFirstLetter(key)}`;
// surround it with try/catch, otherwise all unexpected properties in
// data object will break your code.
try {
// finally, use it.
myFunctions[name](data[key]);
} catch (error) {
console.log(name, 'does not exist');
console.log(error);
}
}
}
}
}
}
가장 좋은 방법은 다음과 같은 동적 함수 목록으로 객체를 만드는 것입니다.
const USER = 'user';
const userModule = {
[USER + 'Action'] : function () { ... },
[USER + 'OnClickHandler'] : function () { ... },
[USER + 'OnCreateHook'] : function () { ... },
}
여기에 명백한 내용이 없을 수도 있지만 이름을 추가하는 것이 잘못된 것은 무엇입니까? 함수는 이름에 관계없이 호출됩니다. 이름은 범위 지정 목적으로 만 사용됩니다. 변수에 할당하고 범위 내에 있으면 호출 할 수 있습니다. 모자 발생은 함수로 발생하는 변수를 실행하는 것입니다. 디버깅 할 때 식별을 위해 이름이 있어야하는 경우 키워드 함수와 여는 중괄호 사이에 삽입합니다.
var namedFunction = function namedFunction (a,b) {return a+b};
alert(namedFunction(1,2));
alert(namedFunction.name);
alert(namedFunction.toString());
또 다른 방법은 이름이 변경된 외부 shim에 함수를 래핑하는 것입니다. 주변 네임 스페이스를 더럽 히지 않으려는 경우 외부 래퍼로 전달할 수도 있습니다. 실제로 문자열에서 함수를 동적으로 생성하고 싶다면 (대부분의 예제가 수행하는) 소스 이름을 변경하여 원하는 작업을 수행하는 것은 간단합니다. 그러나 다른 곳에서 호출 될 때 기능에 영향을주지 않고 기존 함수의 이름을 바꾸려면 shim이이를 달성하는 유일한 방법입니다.
(function(renamedFunction) {
alert(renamedFunction(1,2));
alert(renamedFunction.name);
alert(renamedFunction.toString());
alert(renamedFunction.apply(this,[1,2]));
})(function renamedFunction(){return namedFunction.apply(this,arguments);});
function namedFunction(a,b){return a+b};
name
은 이제 변수와 속성에서 추론되므로 유용합니다. 스택 추적에도 사용됩니다. 예 var fn = function(){}; console.log(fn.name)
. 변경이 불가능하므로 나중에 변경할 수 없습니다. 모든 함수의 이름을 지정하는 팩토리 메소드를 작성하면 fn
디버깅이 더 어려워집니다.
this["instance"] = function() { }