私は次のような文字列を得ました:
settings.functionName + '(' + t.parentNode.id + ')';
私はそのように関数呼び出しに変換したいのですが。
clickedOnItem(IdofParent);
もちろんこれはJavaScriptで行う必要があります。私がsettings.functionName + '(' + t.parentNode.id + ')';
に対してアラートを出したとき、それはすべてを正しくしているようです。それが変換される関数を呼び出すだけです。
伝説:
settings.functionName = clickedOnItem
t.parentNode.id = IdofParent
私はevalが嫌いなので見て、私は 一人じゃない :
var fn = window[settings.functionName];
if(typeof fn === 'function') {
fn(t.parentNode.id);
}
編集:@ Mahanのコメントに答えて:この場合、settings.functionName
は"clickedOnItem"
になります。これにより、実行時にvar fn = window[settings.functionName];
がvar fn = window["clickedOnItem"]
に変換され、function clickedOnItem (nodeId) {}
への参照が取得されます。変数内の関数への参照を取得したら、「変数を呼び出す」ことでこの関数を呼び出すことができます。つまり、fn(t.parentNode.id)
はclickedOnItem(t.parentNode.id)
と等しく、OPが望んでいたものです。
より完全な例:
/* Somewhere: */
window.settings = {
/* [..] Other settings */
functionName: 'clickedOnItem'
/* , [..] More settings */
};
/* Later */
function clickedOnItem (nodeId) {
/* Some cool event handling code here */
}
/* Even later */
var fn = window[settings.functionName];
/* note that settings.functionName could also be written
as window.settings.functionName. In this case, we use the fact that window
is the implied scope of global variables. */
if(typeof fn === 'function') {
fn(t.parentNode.id);
}
window[settings.functionName](t.parentNode.id);
Eval()は必要ありません
スコープをサポートしながら、これを行うためのより一般的な方法は次のとおりです。
// Get function from string, with or without scopes (by Nicolas Gauthier)
window.getFunctionFromString = function(string)
{
var scope = window;
var scopeSplit = string.split('.');
for (i = 0; i < scopeSplit.length - 1; i++)
{
scope = scope[scopeSplit[i]];
if (scope == undefined) return;
}
return scope[scopeSplit[scopeSplit.length - 1]];
}
それが何人かの人々を助けることを願っています。
JavaScriptには、文字列を評価してコードとして実行する eval
関数があります。
eval(settings.functionName + '(' + t.parentNode.id + ')');
eval()はそのために必要な関数ですが、evalの使用を最小限に抑えるためにこれらのうちの1つを試すことをお勧めします。うまくいけば、それらのうちの1つがあなたにとって理にかなっているでしょう。
機能を保存する
関数を文字列としてではなく関数として格納し、後で関数として使用します。あなたが実際に関数を保存する場所はあなた次第です。
var funcForLater = clickedOnItem;
// later is now
funcForLater(t.parentNode.id);
または
someObject.funcForLater = clickedOnItem;
// later is now
(someObject.funcForLater)(t.parentNode.id);
ストア機能名
関数名を文字列として格納する必要がある場合でも、次のようにすると複雑さを最小限に抑えることができます。
(eval(settings.functionName))(t.parentNode.id);
これにより、作成して評価する必要があるJavascriptの量が最小限に抑えられます。
ハンドラの辞書
あなたが必要とするかもしれない全てのアクション関数をオブジェクトの中に入れ、そしてそれらを文字列を使って辞書形式で呼び出す。
// global
itemActions = { click: clickedOnItem, rightClick: rightClickedOnItem /* etc */ };
// Later...
var actionName = "click"; // Or wherever you got the action name
var actionToDo = itemActions[actionName];
actionToDo(t.parentNode.id);
(注意:代わりにここでitemActions[actionName](t.parentNode.id);
という構文を使用した場合、関数はitemActions
のメソッドとして呼び出されます。)
私は最初の答えが好きで、evalが嫌いですが、他の方法(evalに似た方法)があることを付け加えたいと思います。しかし、場合によっては、ajaxの呼び出しの前後にjavascriptコードを呼び出したいことがあります。このコードをajaxではなくカスタム属性に含めると、次のように使用できます。
var executeBefore = $(el).attr("data-execute-before-ajax");
if (executeBefore != "") {
var fn = new Function(executeBefore);
fn();
}
あるいは、複数回呼び出す必要がある場合は、これを関数キャッシュに保存します。
繰り返しますが、他の方法がある場合は、evalやこの方法を使用しないでください。
settings.functionName
がすでに関数の場合は、これを実行できます。
settings.functionName(t.parentNode.id);
そうでなければ、これはsettings.functionName
が単なる関数の名前である場合にも機能するはずです。
if (typeof window[settings.functionName] == "function") {
window[settings.functionName](t.parentNode.id);
}
私は、文字列として関数名を取り、それを呼び出し、そして関数に引数を渡すことができることを望みました。この質問に対する選択された答えを得ることができませんでしたが、これ answer で正確に説明されています。ここに短いデモがあります。
function test_function(argument) {
alert('This function ' + argument);
}
functionName = 'test_function';
window[functionName]('works!');
これは複数の引数に対しても機能します。
従来のwindow['someFunctionName']()
は最初はうまく機能しなかったので、これには少し時間がかかりました。私の関数の名前はデータベースからのAJAXレスポンスとして引き出されていました。また、何らかの理由で、私の関数はウィンドウの範囲外で宣言されていたので、これを修正するためには、呼び出し元の関数を書き直す必要がありました
function someFunctionName() {}
に
window.someFunctionName = function() {}
そこから、私はwindow['someFunctionName']()
を簡単に呼び出すことができます。これが誰かに役立つことを願っています!
Nicolas Gauthierの答えに基づく:
var strng = 'someobj.someCallback';
var data = 'someData';
var func = window;
var funcSplit = strng.split('.');
for(i = 0;i < funcSplit.length;i++){
//We maybe can check typeof and break the bucle if typeof != function
func = func[funcSplit[i]];
}
func(data);
私はこのようなものを使うのが好きです。
window.callbackClass['newFunctionName'] = function(data) { console.log(data) };
...
window.callbackClass['newFunctionName'](data);
例えばnode.jsのように、CommonJS仕様を使用するJavaScriptでは、以下に示すものを実行できます。 window
オブジェクトで定義されていなくても、文字列で変数にアクセスするのにかなり便利です。 MyClass.jsという名前のCommonJSモジュール内に定義されたMyClass
という名前のクラスがある場合
// MyClass.js
var MyClass = function() {
// I do stuff in here. Probably return an object
return {
foo: "bar"
}
}
module.exports = MyClass;
これで、MyOtherFile.jsという別のファイルからこの素敵な魔術を実行できます。
// MyOtherFile.js
var myString = "MyClass";
var MyClass = require('./' + myString);
var obj = new MyClass();
console.log(obj.foo); // returns "bar"
CommonJSがこのような喜びであるもう1つの理由。