ජාවාස්ක්‍රිප්ට් ශ්‍රිතයක් එහි නමක් ලෙස මා සතුව ඇති විට එය ක්‍රියාත්මක කරන්නේ කෙසේද?


1069

මට ජාවාස්ක්‍රිප්ට් හි ශ්‍රිතයක නමක් ඇත. මට එය පසුව ක්‍රියාකාරී ඇමතුමක් බවට පරිවර්තනය කරන්නේ කෙසේද?

තත්වයන් මත පදනම්ව, මට ක්‍රමයට විවිධ තර්ක ඉදිරිපත් කිරීමට අවශ්‍ය විය හැකිය.

සමහර ශ්‍රිතවල ස්වරූපය ගනී namespace.namespace.function(args[...]).

Answers:


1459

භාවිතා නොකරන්න evalඔබ මිස පරම, ධනාත්මක වෙනත් කිසිදු විකල්පයක් තියෙනවා.

සඳහන් කර ඇති පරිදි, මෙවැනි දෙයක් භාවිතා කිරීම හොඳම ක්‍රමය වනු ඇත:

window["functionName"](arguments);

කෙසේ වෙතත්, එය නාම අවකාශයේ ශ්‍රිතයක් සමඟ ක්‍රියා නොකරනු ඇත:

window["My.Namespace.functionName"](arguments); // fail

ඔබ එය කරන්නේ මෙයයි:

window["My"]["Namespace"]["functionName"](arguments); // succeeds

එය පහසු කිරීම සහ යම් නම්‍යතාවයක් ලබා දීම සඳහා, මෙහි පහසුව සඳහා ශ්‍රිතයක් ඇත:

function executeFunctionByName(functionName, context /*, args */) {
  var args = Array.prototype.slice.call(arguments, 2);
  var namespaces = functionName.split(".");
  var func = namespaces.pop();
  for(var i = 0; i < namespaces.length; i++) {
    context = context[namespaces[i]];
  }
  return context[func].apply(context, args);
}

ඔබ එය එසේ හඳුන්වනු ඇත:

executeFunctionByName("My.Namespace.functionName", window, arguments);

සටහන, ඔබට අවශ්‍ය ඕනෑම සන්දර්භයකින් ඔබට සමත් විය හැකිය, එබැවින් මෙය ඉහත ආකාරයටම කරනු ඇත:

executeFunctionByName("Namespace.functionName", My, arguments);

4
ඔබ දන්නවා ඔබට සම්පූර්ණ "ෆන්ක්" ඉදිකිරීම අවශ්‍ය නොවන බව? "context.apply" පමණක් හොඳයි
annakata

16
ෂුවර්, මම එය දනිමි - නමුත් මා විසින් ශ්‍රිතය ලියා ඇති ආකාරය එය කියවන අයට යම් පැහැදිලි කිරීමක් සපයයි. මම මෙම ක්‍රියාව ලිව්වේ එය කියවන අයට යම් උපකාරයක් අවශ්‍ය විය හැකි බව වටහා ගනිමිනි. ඔබ ඉල්ලූ බැවින් මම විකල්පයක් ලබා දෙන්නෙමි ...
ජේසන් බන්ටිං

110
එය සීරීමට - කේතය ප්‍රමාණවත් තරම් පැහැදිලි වන අතර දන්නා අය දනිති. ඔබ මා හා සමාන නම් සහ ඔබ කරන්නේ කුමක්දැයි දන්නේ නම්, ඔබ මෙම කේතය භාවිතා කළේ නම් ඔබට තනිවම එවැනි වෙනස්කම් කළ හැකිය. Stack Overflow යනු අන් අය දැනුවත් කිරීම සඳහා වන අතර නවකයෙකුට තේරුම් ගැනීමට මගේ කේතය පහසු යැයි මම සිතමි. ස්තූතියි!
ජේසන් බන්ටිං

4
කවුළුව ["funcName"] නිර්වචනය නොකොට නැවත පැමිණෙන තත්වයක් තිබේද? මට මේ මොහොතේ ඇති ගැටලුව එයයි. ඇමතුම් කේතය සහ ශ්‍රිතය වෙනම js ගොනු දෙකකින් අර්ථ දක්වා ඇත. මම ඒවා එකම ගොනුවකට එක් කිරීමට උත්සාහ කළ නමුත් එයින් කිසිදු වෙනසක් සිදු නොවීය.
codemonkey

5
මම හිතන්නේ මෙතන ප්‍රශ්නයක් තියෙනවා. ඔබ අමතන විට My.Namespace.functionName(), වස්තුව thisවෙත යොමු වේ My.Namespace. නමුත් ඔබ අමතන විට එකම දේ වෙත යොමු වීමට executeFunctionByName("My.Namespace.functionName", window)ක්‍රමයක් නොමැත this. සමහර විට එය අවසාන නාම අවකාශය විෂය පථය ලෙස භාවිතා කළ යුතුය, නැතහොත් windowනාම අවකාශ නොමැති නම්. නැතහොත් පරාමිතිය තර්කයක් ලෙස සඳහන් කිරීමට පරිශීලකයාට ඉඩ දිය හැකිය.
ජේ.

101

ජේසන් බන්ටිංගේ ඉතා ප්‍රයෝජනවත් ක්‍රියාකාරිත්වයේ තරමක් වෙනස් කළ අනුවාදයක් පළ කිරීමට සිතුවෙමි .

පළමුව, පෙත්ත () සඳහා දෙවන පරාමිතියක් සැපයීමෙන් මම පළමු ප්‍රකාශය සරල කර ඇත්තෙමි . මුල් අනුවාදය IE හැර අනෙකුත් සියලුම බ්‍රව්සර්වල හොඳින් ක්‍රියාත්මක විය.

දෙවනුව, මම මෙය ආපසු ප්‍රකාශයේ සන්දර්භය සමඟ ප්‍රතිස්ථාපනය කර ඇත ; එසේ නොමැති නම්, මෙය සැමවිටම ඉලක්ක ශ්‍රිතය ක්‍රියාත්මක වන විට කවුළුවට යොමු වේ .

function executeFunctionByName(functionName, context /*, args */) {
    var args = Array.prototype.slice.call(arguments, 2);
    var namespaces = functionName.split(".");
    var func = namespaces.pop();
    for (var i = 0; i < namespaces.length; i++) {
        context = context[namespaces[i]];
    }
    return context[func].apply(context, args);
}

"FunctionName" ඇත්ත වශයෙන්ම තිබේදැයි බැලීමට කිසිදු චෙක්පතක් නොමැත?
Crashalot

මම හිතන්නේ මැක්ගේ පිළිතුර අවතක්සේරු කර ඇත. මම විශේෂ expert යෙක් නොවුනත් එය හොඳින් සිතා බලා ශක්තිමත් බව පෙනේ.
මාටින් හැන්සන් ලෙනොක්ස්

66

මෙම අනෙක් ප්‍රශ්නයට පිළිතුර ඔබට එය කරන්නේ කෙසේදැයි පෙන්වයි: පයිතන්ගේ ප්‍රදේශවාසීන්ට සමාන ජාවාස්ක්‍රිප්ට් ()?

මූලික වශයෙන්, ඔබට පැවසිය හැකිය

window["foo"](arg1, arg2);

හෝ වෙනත් බොහෝ අය යෝජනා කර ඇති පරිදි, ඔබට eval භාවිතා කළ හැකිය:

eval(fname)(arg1, arg2);

ඔබ අතිශයින්ම අනාරක්ෂිත වුවත්, ඔබ කළ යුත්තේ කුමක්ද යන්න පිළිබඳව ඔබට පූර්ණ විශ්වාසයක් නොමැති නම්.


6
පළමු පෝරමය වඩා යෝග්‍ය වේ
annakata

20
අනෙක් සියල්ල අසමත් වූ විට පමණක් අවසාන ක්‍රමය ලෙස ev භාවිතා කරන්න.
ජේසන් බන්ටිං

1
එය ... නමුත් එය මෙවැනි කාර්යයන් සමඟ ක්‍රියා කරයිද: xyz (args)?
Kieron

@ කෙයිරොන්: ඔව්. මගේ පිළිතුර පහතින් බලන්න
annakata

56

ඔබට මෙය කළ නොහැකිද:

var codeToExecute = "My.Namespace.functionName()";
var tmpFunc = new Function(codeToExecute);
tmpFunc();

ඔබට මෙම ක්‍රමය භාවිතා කර වෙනත් ඕනෑම ජාවාස්ක්‍රිප්ට් ක්‍රියාත්මක කළ හැකිය.


3
ශ්‍රිතය සමඟ තර්ක පවා සම්මත වූ විට ක්‍රියා කරයි
adeel41

ශ්‍රිත ප්‍රතිලාභ ගැන කුමක් කිව හැකිද?
පීටර් ඩෙනෙව්

12
එය වෙනස් වන්නේ eval("My.Namespace.functionName()");කෙසේද?
developerbmw

@PeterDenev පමණක් පළමු මාර්ගය වෙනස්var codeToExecute = "return My.Namespace.functionName()";
developerbmw

2
vedeveloperbmw, මෙන්න පිළිතුර stackoverflow.com/questions/4599857/…
තේජාස්වි හෙග්ඩේ

50

මම හිතන්නේ මෙය කිරීමට අලංකාර ක්‍රමයක් වන්නේ හැෂ් වස්තුවක ඔබේ කාර්යයන් නිර්වචනය කිරීමයි. එවිට ඔබට එම ශ්‍රිතයන් ගැන හැෂ් වෙතින් නූලක් භාවිතා කළ හැකිය. උදා

var customObject = {
  customFunction: function(param){...}
};

එවිට ඔබට ඇමතිය හැකිය:

customObject['customFunction'](param);

එහිදී CustomFunction යනු ඔබේ වස්තුවෙහි අර්ථ දක්වා ඇති ශ්‍රිතයකට ගැලපෙන නූලකි.


@ibsenv, මෙම ප්‍රතිචාරය හොඳම ලෙස හඳුනා ගැනීමට මට උදව් කිරීමට ඔබගේ අදහස් දැක්වීමට ස්තූතියි. මම ක්‍රියාකාරී වස්තු සමූහයක් නිර්මාණය කළ අතර එය කල්දැමූ.ප්‍රොමිසස් සමූහයක් නිර්මාණය කිරීමට භාවිතා කළෙමි. මම නියැදි කේත කිහිපයක් පහතින් තැබුවෙමි. (මට නව පිළිතුරක් නිර්මාණය කිරීමට සහ රූබන්ගේ ප්‍රතිචාරය ලබා ගැනීමට අවශ්‍ය නොවීය .)
user216661

getMyData (arrayOfObjectsWithIds) function var functionArray = arrayOfObjectsWithIds.map (ශ්‍රිතය (අගය) {ආපසු {myGetDataFunction: MyService.getMyData (value.id)}; q.defer (); getDataFunction.myGetDataFunction.success (ශ්‍රිතය (දත්ත) {deferred.resolve (දත්ත)}). දෝෂය (ශ්‍රිතය (දෝෂය) {deferred.reject ();}); ආපසු කල්තබන $ q.all (පොරොන්දු) .එවිට (ශ්‍රිතය (dataArray) {// දේවල් කරන්න})};
user216661

මෙය විශිෂ්ට ලෙස ක්‍රියා කරයි, එහි ක්‍රියාකාරීත්වයක් තිබේදැයි තහවුරු කර ගැනීම සඳහා මම අවධාරනය / ලොඩාෂ් පමණක් එක් කරමි. ඉන්පසු ධාවනය කරන්න
elporfirio

37

ES6 සමඟ ඔබට නම අනුව පන්ති ක්‍රම වෙත පිවිසිය හැකිය:

class X {
  method1(){
    console.log("1");
  }
  method2(){
    this['method1']();
    console.log("2");
  }
}
let x  = new X();
x['method2']();

ප්‍රතිදානය වනුයේ:

1
2

1
හොඳම javascript PURE ... දෙයියනේ .. මකන්න පන්තිය වැඩ කරන්නේ නැහැ. ස්තූතියි!
කිං රයිඩර්

1
මෙය මා දිගු කලක් තිස්සේ සොයමින් සිටි දෙයයි. ස්තූතියි!
පලඩිඑන්

ES2015 ට මෙහි කිසිදු සම්බන්ධයක් නැත. පිරිසිදු වස්තූන් භාවිතා කරමින් ඔබට එකම ඉලක්කය සපුරා ගත හැකිය, නැතහොත් මූලාකෘති නියෝජිත කණ්ඩායම හරහා Object.create(). const myObj = {method1 () {console.log ('1') method, method2 () {console.log ('2')}} myObj ['method1'] (); // 1 myObj ['method2'] (); // 2
sminutoli

1
මේ රත්තරන් !!! මම පුදුම වෙනවා මම මීට පෙර කවදාවත් මේ ගැන නොසිතුවා. හොඳයි !!!
thxmike

අපගේ ඉලක්කය සපුරා ගැනීම සඳහා ඇති හොඳම ක්‍රමය මෙය යැයි මම සිතමි.
ක්‍රිස් ජුන්ග්

24

කරුණු දෙකක්:

  • එවාල් වළක්වා ගන්න, එය භයානක හා මන්දගාමී ය

  • දෙවනුව, ඔබේ ක්‍රියාකාරිත්වය පවතින්නේ කොතැනද යන්න ගැටළුවක් නොවේ, “ගෝලීය” බව අදාළ නොවේ. x.y.foo()හරහා සක්රිය කළ හැකිය x.y['foo']()හෝ x['y']['foo']()හෝ window['x']['y']['foo'](). ඔබට මේ ආකාරයට දින නියමයක් නොමැතිව දම්වැල දැමිය හැකිය.


1
නමුත් ඔබට xyz () අමතන්න කවුළුව ['xyz'] () කළ නොහැක
nickf

17

සියලුම පිළිතුරු උපකල්පනය කරන්නේ ගෝලීය විෂය පථය (කවුළුව) හරහා කාර්යයන් වෙත ප්‍රවේශ විය හැකි බවයි. කෙසේ වෙතත්, OP මෙම උපකල්පනය සිදු කළේ නැත.

කාර්යයන් දේශීය විෂය පථයක (හෝ වසා දැමීම) ජීවත් වන්නේ නම් සහ වෙනත් දේශීය වස්තුවක් මගින් යොමු නොකෙරේ නම්, අවාසනාව: ඔබට eval()AFAIK භාවිතා කළ යුතුය , ජාවාස්ක්‍රිප්ට් හි දේශීය ක්‍රියාකාරිත්වය ගතිකව අමතන්න බලන්න


2
මචන් (හෝ ඩුඩෙට්), එය පෙන්වා දීම ගැන ඔබට බොහෝම ස්තූතියි! මම හිතුවේ මට තත්පරයකට පිස්සු හැදෙනවා කියලයි.
Funktr0n

15

ඔබ සිටින ස්ථානය අනුව ඔබටද භාවිතා කළ හැකිය:

this["funcname"]();
self["funcname"]();
window["funcname"]();
top["funcname"]();
globalThis["funcname"]();

හෝ, nodejs වලින්

global["funcname"]()

13

ඔබට අවශ්‍ය වන්නේ ඔබේ නූල දර්ශකයකට පරිවර්තනය කිරීමයි window[<method name>]. උදාහරණයක්:

var function_name = "string";
function_name = window[function_name];

දැන් ඔබට එය දර්ශකයක් මෙන් භාවිතා කළ හැකිය.


මෙය වඩා ආරක්ෂිත ක්‍රමයක් බව පෙනේ.
ජේම්ස් පූලෝස්

12

ජේසන් බන්ටිංගේ / ඇලෙක්ස් නසරොව්ගේ විශිෂ් answer පිළිතුරු සඳහා මගේ දායකත්වය මෙන්න, එහිදී ක්‍රෂාලොට් විසින් ඉල්ලා ඇති දෝෂ පරීක්ෂා කිරීම ඇතුළත් වේ.

මෙම (සංක්ෂිප්ත) පෙරවදන අනුව:

a = function( args ) {
    console.log( 'global func passed:' );
    for( var i = 0; i < arguments.length; i++ ) {
        console.log( '-> ' + arguments[ i ] );
    }
};
ns = {};
ns.a = function( args ) {
    console.log( 'namespace func passed:' );
    for( var i = 0; i < arguments.length; i++ ) {
        console.log( '-> ' + arguments[ i ] ); 
    }
};
name = 'nsa';
n_s_a = [ 'Snowden' ];
noSuchAgency = function(){};

ඉන්පසු පහත ශ්‍රිතය:

function executeFunctionByName( functionName, context /*, args */ ) {
    var args, namespaces, func;

    if( typeof functionName === 'undefined' ) { throw 'function name not specified'; }

    if( typeof eval( functionName ) !== 'function' ) { throw functionName + ' is not a function'; }

    if( typeof context !== 'undefined' ) { 
        if( typeof context === 'object' && context instanceof Array === false ) { 
            if( typeof context[ functionName ] !== 'function' ) {
                throw context + '.' + functionName + ' is not a function';
            }
            args = Array.prototype.slice.call( arguments, 2 );

        } else {
            args = Array.prototype.slice.call( arguments, 1 );
            context = window;
        }

    } else {
        context = window;
    }

    namespaces = functionName.split( "." );
    func = namespaces.pop();

    for( var i = 0; i < namespaces.length; i++ ) {
        context = context[ namespaces[ i ] ];
    }

    return context[ func ].apply( context, args );
}

ජාවාස්ක්‍රිප්ට් ශ්‍රිතයක් නමින් ගබඩා කර ඇති නමකින් හෝ ගෝලීයව, තර්ක සමඟ හෝ රහිතව (අරාව වස්තු ඇතුළුව) ඇමතීමට ඔබට ඉඩ සලසයි.

නියැදි ප්‍රතිදානය එය ක්‍රියා කරන ආකාරය පෙන්වයි:

// calling a global function without parms
executeFunctionByName( 'a' );
  /* OUTPUT:
  global func passed:
  */

// calling a global function passing a number (with implicit window context)
executeFunctionByName( 'a', 123 );
  /* OUTPUT:
  global func passed:
  -> 123
  */

// calling a namespaced function without parms
executeFunctionByName( 'ns.a' );
  /* OUTPUT:
  namespace func passed:
  */

// calling a namespaced function passing a string literal
executeFunctionByName( 'ns.a', 'No Such Agency!' );
  /* OUTPUT:
  namespace func passed:
  -> No Such Agency!
  */

// calling a namespaced function, with explicit context as separate arg, passing a string literal and array 
executeFunctionByName( 'a', ns, 'No Such Agency!', [ 007, 'is the man' ] );
  /* OUTPUT:
  namespace func passed:
  -> No Such Agency!
  -> 7,is the man
  */

// calling a global function passing a string variable (with implicit window context)
executeFunctionByName( 'a', name );
  /* OUTPUT:
  global func passed:
  -> nsa
  */

// calling a non-existing function via string literal
executeFunctionByName( 'n_s_a' );
  /* OUTPUT:
  Uncaught n_s_a is not a function
  */

// calling a non-existing function by string variable
executeFunctionByName( n_s_a );
  /* OUTPUT:
  Uncaught Snowden is not a function
  */

// calling an existing function with the wrong namespace reference
executeFunctionByName( 'a', {} );
  /* OUTPUT:
  Uncaught [object Object].a is not a function
  */

// calling no function
executeFunctionByName();
  /* OUTPUT:
  Uncaught function name not specified
  */

// calling by empty string
executeFunctionByName( '' );
  /* OUTPUT:
  Uncaught  is not a function
  */

// calling an existing global function with a namespace reference
executeFunctionByName( 'noSuchAgency', ns );
  /* OUTPUT:
  Uncaught [object Object].noSuchAgency is not a function
  */

ඩන්නෝ ... එය ඉතා හොඳ උත්සාහයක්, එය පැහැදිලිය. නමුත් මට "ඉතා පුළුල්" ලෙස
පෙනේ

2
හහ්? SO යනු ප්‍රශ්න / පිළිතුරු / ඉගැන්වීමේ වේදිකාවකි. ආලෝකය විහිදුවාලීමට බලාපොරොත්තු විය හැකි සියලු උදාහරණ මම සතුටින් ලබා දෙමි. මට නම් එය කාරණයකි .
මැක්

ඔබ කෙසේ හෝ ශ්‍රිත නාමය ඉවත් කරන්නේ නම්, එය පමණක් භාවිතා නොකරන්නේ මන්ද?
දත්ත

මෙය මට වැඩ කරන්නේ නැත. මට නම් අවකාශයේ ශ්‍රිතයක් ඇත abcd මෙහි d යනු ශ්‍රිත නාමයයි. if( typeof context[ functionName ] !== 'function' )සන්දර්භය - කවුළුව - නිර්වචනය කර ඇති, වස්තුවක් සහ අරාවක් වන හෙයින් , ක්‍රියාත්මක වන ක්‍රියාකාරීත්වයේ ඇමතුම අසමත් වේ, නමුත් පිළිගත් ගැටලුවක් ලෙස හඳුනාගෙන ඇති පරිදි කවුළුව ['abcd'] නොපවතී. පිළිතුර: window["My.Namespace.functionName"](arguments); // fail
akousmata

9

ඔබට ගෝලීය ශ්‍රිතයක් වෙනුවට වස්තුවක ශ්‍රිතයක් ඇමතීමට අවශ්‍ය නම් window["functionName"]. ඔබට එය එසේ කළ හැකිය;

var myObject=new Object();
myObject["functionName"](arguments);

උදාහරණයක්:

var now=new Date();
now["getFullYear"]()

8

පරෙස්සම් වෙන්න!!!

හේතු දෙකක් නිසා ජාවාස්ක්‍රිප්ට් හි නූලක් මඟින් ශ්‍රිතයක් ඇමතීමෙන් වැළකී සිටීමට උත්සාහ කළ යුතුය:

හේතුව 1: සමහර කේත අපැහැදිලි කරන්නන් ඔබේ කේතය විනාශ කරනු ඇත, මන්ද ඔවුන් ක්‍රියාකාරී නම් වෙනස් කරන අතර එමඟින් නූල අවලංගු වේ.

හේතුව 2: මෙම ක්‍රමවේදය භාවිතා කරන කේතය නඩත්තු කිරීම වඩා දුෂ්කර බැවින් නූලකින් හැඳින්වෙන ක්‍රමවල භාවිතයන් සොයා ගැනීම වඩා දුෂ්කර ය.


7

මෙන්න මගේ Es6 ප්‍රවේශය මඟින් ඔබේ ශ්‍රිතය එහි නම ලෙස හෝ එහි ක්‍රියාකාරී නාමයෙන් ඇමතීමට ඔබට හැකියාව ලබා දෙන අතර විවිධ වර්ගයේ තර්ක ගණනකට විවිධ වර්ගවල ශ්‍රිත වෙත යැවීමට ඔබට හැකි වේ:

function fnCall(fn, ...args)
{
  let func = (typeof fn =="string")?window[fn]:fn;
  if (typeof func == "function") func(...args);
  else throw new Error(`${fn} is Not a function!`);
}


function example1(arg1){console.log(arg1)}
function example2(arg1, arg2){console.log(arg1 + "  and   " + arg2)}
function example3(){console.log("No arguments!")}

fnCall("example1", "test_1");
fnCall("example2", "test_2", "test3");
fnCall(example3);
fnCall("example4"); // should raise an error in console


6

SetTimeout ගැන සඳහනක් නොකිරීම පුදුමයට කරුණකි.

තර්කයකින් තොරව ශ්‍රිතයක් ක්‍රියාත්මක කිරීමට:

var functionWithoutArguments = function(){
    console.log("Executing functionWithoutArguments");
}
setTimeout("functionWithoutArguments()", 0);

තර්ක සමඟ ක්‍රියා කිරීම සඳහා:

var functionWithArguments = function(arg1, arg2) {
    console.log("Executing functionWithArguments", arg1, arg2);
}
setTimeout("functionWithArguments(10, 20)");

ගැඹුරින් නාම අවකාශ ශ්‍රිතය ක්‍රියාත්මක කිරීම සඳහා:

var _very = {
    _deeply: {
        _defined: {
            _function: function(num1, num2) {
                console.log("Execution _very _deeply _defined _function : ", num1, num2);
            }
        }
    }
}
setTimeout("_very._deeply._defined._function(40,50)", 0);

මෙය ප්‍රශ්නයට පිළිතුරක් සපයන්නේ නැත. කතුවරයකු විවේචනය කිරීමට හෝ පැහැදිලි කිරීමක් ඉල්ලා සිටීමට, ඔවුන්ගේ ලිපියට පහළින් සටහනක් තබන්න - ඔබට සැමවිටම ඔබේ තනතුරු ගැන අදහස් දැක්විය හැකි අතර, ඔබට ප්‍රමාණවත් කීර්තියක් ලැබීමෙන් පසු ඔබට ඕනෑම තනතුරක් පිළිබඳව අදහස් දැක්වීමට හැකි වනු ඇත .
AstroCB

කරුණාකර ඔබ runMeතර්ක කිහිපයක් සමඟ කතා කරන්නේ කෙසේද යන්න පිළිබඳ උදාහරණයක් එක් කරන්න .
ශබ්දකෝෂ

1
@lexicore මම සමාලෝචන පෝලිමක මකාදැමීමට ඡන්දය දුන්නෙමි , මන්ද එය පැහැදිලිවම ප්‍රශ්නයට සැලකිය යුතු පිළිතුරක් ලබා නොදෙන අතර එය තනිවම වටිනාකමක් නැති බැවිනි.
AstroCB

1
පෝලිම් විදැහුම් කිරීම අවසන් කිරීම සඳහා මෙම ක්‍රමය විශාල දෝෂයක් ඇති කළ හැකි අතර එමඟින් මෙම ඇමතුම අසමමුහුර්ත වේ
පීටර්එම්

1
මම මෙම පිළිතුරට කැමතියි, එය මගේ අවශ්‍යතා සඳහා වැඩ කරන බව පෙනේ.
ක්වින්ටන්

3

එබැවින්, අනෙක් අය පැවසූ පරිදි, අනිවාර්යයෙන්ම හොඳම විකල්පය නම්:

window['myfunction'](arguments)

හා සමාන ජේසන් Bunting පවසයි ඔබේ කාර්යය නම වස්තුවක් ඇතුළත් නම් එය වැඩ කරන්නේ නැහැ,:

window['myobject.myfunction'](arguments); // won't work
window['myobject']['myfunction'](arguments); // will work

ඉතින් මගේ ශ්‍රිතයේ අනුවාදය මෙන්න සියලු කාර්යයන් නාමයෙන් ක්‍රියාත්මක කරනු ඇත (වස්තුවක් ඇතුළුව හෝ නැත):

my = {
    code : {
        is : {
            nice : function(a, b){ alert(a + "," + b); }
        }
    }
};

guy = function(){ alert('awesome'); }

function executeFunctionByName(str, args)
{
    var arr = str.split('.');
    var fn = window[ arr[0] ];
    
    for (var i = 1; i < arr.length; i++)
    { fn = fn[ arr[i] ]; }
    fn.apply(window, args);
}

executeFunctionByName('my.code.is.nice', ['arg1', 'arg2']);
executeFunctionByName('guy');


3
  let t0 = () => { alert('red0') }
  var t1 = () =>{ alert('red1') }
  var t2 = () =>{ alert('red2') }
  var t3 = () =>{ alert('red3') }
  var t4 = () =>{ alert('red4') }
  var t5 = () =>{ alert('red5') }
  var t6 = () =>{ alert('red6') }

  function getSelection(type) {
    var evalSelection = {
      'title0': t0,
      'title1': t1,
      'title2': t2,
      'title3': t3,
      'title4': t4,
      'title5': t5,
      'title6': t6,
      'default': function() {
        return 'Default';
      }
    };
    return (evalSelection[type] || evalSelection['default'])();
  }
  getSelection('title1');

තවත් OOP විසඳුමක් ...


2

ජේසන් සහ ඇලෙක්ස්ගේ සටහන් පිළිබඳ තවත් එක් විස්තරයක්. සන්දර්භයට පෙරනිමි අගයක් එක් කිරීම ප්‍රයෝජනවත් බව මට පෙනී ගියේය. context = context == undefined? window:context;ශ්‍රිතයේ ආරම්භයේදීම තබන්න . ඔබ windowකැමති ඕනෑම සන්දර්භයකට වෙනස් කළ හැකිය , එවිට ඔබේ පෙරනිමි සන්දර්භය තුළ ඔබ මෙය අමතන සෑම අවස්ථාවකම එකම විචල්‍යයකින් සමත් වීමට අවශ්‍ය නොවේ.


2

ජේසන් බන්ටිංගේ පිළිතුරට එකතු කිරීම සඳහා, ඔබ නෝඩ්ජ් හෝ වෙනත් දෙයක් භාවිතා කරන්නේ නම් (මෙය ඩොම් ජේඑස් වලද ක්‍රියාත්මක වේ), ඔබට thisඒ වෙනුවට භාවිතා කළ හැකිය window(මතක තබා ගන්න: එවාල් නපුර :

this['fun'+'ctionName']();

2

මගේ කේතයේ බොහෝ සමාන දෙයක් තිබේ. තෙවන පාර්ශවීය පුස්තකාලයක් සඳහා ඇමතුමක් ලෙස මට යැවිය යුතු ශ්‍රිත නාමයක් අඩංගු සේවාදායකයෙන් ජනනය කරන ලද නූලක් මා සතුව ඇත. ඒ නිසා මට කේතයක් ඇති අතර එය නූල ගෙන ශ්‍රිතයට “දර්ශකයක්” ලබා දෙයි, නැතහොත් එය සොයාගත නොහැකි නම් ශුන්‍ය වේ.

මගේ විසඳුම " ජේසන් බන්ටිංගේ ඉතා ප්‍රයෝජනවත් කාර්යයට " බොහෝ සෙයින් සමාන විය . එය ස්වයංක්රීය-ක්රියාත්මක නොවන මුත්, හා සන්දර්භය සෑම විටම කවුළුව මත වේ. නමුත් මෙය පහසුවෙන් වෙනස් කළ හැකිය.

මෙය යමෙකුට ප්‍රයෝජනවත් වනු ඇතැයි අපේක්‍ෂා කරමු.

/**
 * Converts a string containing a function or object method name to a function pointer.
 * @param  string   func
 * @return function
 */
function getFuncFromString(func) {
    // if already a function, return
    if (typeof func === 'function') return func;

    // if string, try to find function or method of object (of "obj.func" format)
    if (typeof func === 'string') {
        if (!func.length) return null;
        var target = window;
        var func = func.split('.');
        while (func.length) {
            var ns = func.shift();
            if (typeof target[ns] === 'undefined') return null;
            target = target[ns];
        }
        if (typeof target === 'function') return target;
    }

    // return null if could not parse
    return null;
}

2

ඔබට සංකීර්ණ අතරමැදි කාර්යයන් අවශ්‍ය යැයි මම නොසිතමි. නැතහොත් කවුළුව වැනි ගෝලීය විචල්‍යයන් මත රඳා පවතී.

function fun1(arg) {
  console.log(arg);
}

function fun2(arg) {
  console.log(arg);
}

const operations = {
  fun1,
  fun2
};

operations["fun1"]("Hello World");
operations.fun2("Hello World");

// You can use intermediate variables, if you like
let temp = "fun1";
operations[temp]("Hello World");

ආනයනික කාර්යයන් සමඟ ද එය ක්‍රියා කරනු ඇත:

// mode.js
export function fun1(arg) {
  console.log(arg);
}

export function fun2(arg) {
  console.log(arg);
}
// index.js
import { fun1, fun2 } from "./mod";

const operations = {
  fun1,
  fun2
};

operations["fun1"]("Hello World");
operations["fun2"]("Hello World");

එය දේපල ප්‍රවේශය භාවිතා කරන බැවින්, ඔබ මෙහි සොයා ගන්නා සමහර පිළිතුරු වලට පටහැනිව, එය අවම කිරීම හෝ අපැහැදිලි වීම නොනැසී පවතිනු ඇත.



1

වෙනත් උපක්‍රමයක් සඳහන් කිරීම මට විරුද්ධ විය නොහැක, එය ඔබට නොදන්නා තර්ක ගණනක් තිබේ නම් එය ක්‍රියාකාරී නාමය අඩංගු නූලෙහි කොටසක් ලෙස සම්මත වේ. උදාහරණයක් වශයෙන්:

var annoyingstring = 'call_my_func(123, true, "blah")';

ඔබගේ ජාවාස්ක්‍රිප්ට් HTML පිටුවක ක්‍රියාත්මක වන්නේ නම්, ඔබට අවශ්‍ය වන්නේ අදෘශ්‍යමාන සබැඳියකි; ඔබට ගුණාංගයට නූලක් යැවිය හැකි අතර onclick, ඇමතුම් clickක්‍රමය.

<a href="#" id="link_secret"><!-- invisible --></a>

$('#link_secret').attr('onclick', annoyingstring);
$('#link_secret').click();

නැතහොත් <a>ධාවන වේලාවේදී මූලද්‍රව්‍යය සාදන්න .


නිර්මාණාත්මක විසඳුම, නමුත් මෙය වස්තු හෝ අරාව වර්ගයේ තර්ක සඳහා ක්‍රියා නොකරනු ඇත.
ඩෙනිස් හයිඩන්

1
මෙය කබාය යටතේ එවාල් භාවිතා කරයි ... ඇත්තෙන්ම එය කිරීමට පඳුර වටා පහර දෙයි
ජුවාන් මෙන්ඩිස්

1

පහසුම ක්‍රමය නම් මූලද්‍රව්‍යය ඇති ආකාරයට ප්‍රවේශ වීමයි

window.ClientSideValidations.forms.location_form

සමාන වේ

window.ClientSideValidations.forms['location_form']

1

ඔබට ජාවාස්ක්‍රිප්ට් ශ්‍රිතය ඇමතිය eval("functionname as string")හැකිය. පහත පරිදි: (eval යනු පිරිසිදු ජාවාස්ක්‍රිප්ට් ශ්‍රිතයකි)

function testfunc(){
    return "hello world";
}

$( document ).ready(function() {

     $("div").html(eval("testfunc"));
});

වැඩ කරන උදාහරණය: https://jsfiddle.net/suatatan/24ms0fna/4/


මෙය ඉතා හොඳින් ක්‍රියාත්මක වන අතර එය ඉතා සරලයි
කාලෝස් ඊ

1
ඒ වගේම ඇත්තටම මන්දගාමීයි.
මාකෝ

1

මෙය මා වෙනුවෙන් වැඩ කරයි:

var command = "Add";
var tempFunction = new Function("Arg1","Arg2", "window." + command + "(Arg1,Arg2)");
tempFunction(x,y);

මම හිතනවා මේක වැඩ කරයි කියලා.


0

භාවිතයෙන් තොරව eval('function()')ඔබට නව ශ්‍රිතයක් නිර්මාණය කළ හැකිය new Function(strName). පහත කේතය FF, Chrome, IE භාවිතයෙන් පරීක්ෂා කරන ලදී.

<html>
<body>
<button onclick="test()">Try it</button>
</body>
</html>
<script type="text/javascript">

  function test() {
    try {    
        var fnName = "myFunction()";
        var fn = new Function(fnName);
        fn();
      } catch (err) {
        console.log("error:"+err.message);
      }
  }

  function myFunction() {
    console.log('Executing myFunction()');
  }

</script>

0
use this

function executeFunctionByName(functionName, context /*, args */) {
      var args = [].slice.call(arguments).splice(2);
      var namespaces = functionName.split(".");
      var func = namespaces.pop();
      for(var i = 0; i < namespaces.length; i++) {
        context = context[namespaces[i]];
      }
      return context[func].apply(context, args);
    }

1
මන්ද? පැහැදිලි කිරීමකින් තොරව පිළිතුරු බොහෝ දුරට නිෂ් .ල ය.
ඩැනියෙල් ඩබ්ලිව්.

0

මූලික බලන්න:

var namefunction = 'jspure'; // String

function jspure(msg1 = '', msg2 = '') { 
  console.log(msg1+(msg2!=''?'/'+msg2:''));
} // multiple argument

// Results ur test
window[namefunction]('hello','hello again'); // something...
eval[namefunction] = 'hello'; // use string or something, but its eval just one argument and not exist multiple

පවත්නා වෙනත් වර්ගයේ ශ්‍රිතය පංතිය වන අතර උදාහරණ ලෙස නිල්ස් පීටර්සෝන් බලන්න


0

ඉතා ප්‍රයෝජනවත් පිළිතුරට ස්තූතියි. මම පාවිච්චි කරන්නේ ජේසන් බන්ටිංගේ ක්‍රියාකාරිත්වය මගේ ව්‍යාපෘති වල කරමි.

විකල්ප කල් ඉකුත් වීමක් සමඟ එය භාවිතා කිරීම සඳහා මම එය දිගු කළෙමි, මන්ද කල් ඉකුත්වීම සැකසීමේ සාමාන්‍ය ක්‍රමය ක්‍රියාත්මක නොවන බැවිනි. අභිෂේකිස්නොට්ගේ ප්‍රශ්නය බලන්න

function executeFunctionByName(functionName, context, timeout /*, args */ ) {
	var args = Array.prototype.slice.call(arguments, 3);
	var namespaces = functionName.split(".");
	var func = namespaces.pop();
	for (var i = 0; i < namespaces.length; i++) {
		context = context[namespaces[i]];
	}
	var timeoutID = setTimeout(
		function(){ context[func].apply(context, args)},
		timeout
	);
    return timeoutID;
}

var _very = {
    _deeply: {
        _defined: {
            _function: function(num1, num2) {
                console.log("Execution _very _deeply _defined _function : ", num1, num2);
            }
        }
    }
}

console.log('now wait')
executeFunctionByName("_very._deeply._defined._function", window, 2000, 40, 50 );

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.