Is it possible to call a method from an object using a string?

Is it possible to call a method from an object using a string?

var elem = $('#test');             //<div id="test"></div>
var str = "attr('id')";  

//This is what I'm trying to achieve
  elem.attr('id');                 //test

//What I've tried so far  
  elem.str;                        //undefined
  elem.str();                      //Object [object Object] has no method 'str'
  var fn = eval(str);              //attr is not defined
  eval(elem.toString()+'.'+str);   //Unexpected identifier

//Only solution I've found so far, 
//but is not an option for me 
//because this code is in a function 
//so the element and method call
//get passed in and I wouldn't know
//what they are
  eval($('#test').attr('id'));     //test
+5
source share
3 answers

UPDATE

This is my final, working answer:
After running this code in the console

theMethod = 'attr("id","foo")'.match(/^([^(]+)\(([^)]*)\)/);
jQuery('#post-form')[theMethod[1]].apply(jQuery('#post-form'),JSON.parse('['+theMethod[2]+']'));

The post-form element now has a new identifier, no problem at all. This works for methods that take multiple arguments, one argument, or no arguments at all. Summary:

theMethod = theInString.match(/^\.?([^(]+)\(([^)]*)\)/);
//added \.? to trim leading dot
//made match in between brackets non-greedy
//dropped the $ flag at the end, to avoid issues with trailing white-space after )
elem[theMethod[1]].apply(elem,JSON.parse('['+theMethod+']'));

What is the safest, most reliable approach I can think of, really


What are you doing DO NOT USE EVAL :

var theMethod = 'attr(\'id\')';
//break it down:
theMethod = theMethod.match(/^([^(]+)\(.*?([^)'"]+).*\)$/);
//returns ["attr('id')", "attr", "id"]
elem[theMethod[1]](theMethod[2]);//calls the method

, (, - JS), jQuery . , , :

$('#foo').attr('id') === $('#foo')['attr']('id');

, , , .

: , , - eval, .


, , ( - : , , ):

theMethod = theMethod.match(/^([^(]+)\(([^)]+)\)$/);
//["attr('id','foo')", "attr", "'id','foo'"] --> regex must now match quotes, too
elem.theMethod[1].apply(elem,JSON.parse('['+theMethod[2]+']'));

/, , (this ), , .

+4

:

  • var result = function.apply(thisArg[, argsArray]);

  • var result = fun.call(thisArg[, arg1[, arg2[, ...]]]);

:

var Sample = function() {
var that = this;

this.sampleMethod = function() {
    return alert("Hello!");
};

this.sampleMethod2 = function(){

    that["sampleMethod"].apply(that);
};  
};

var objImpl = new Sample();

objImpl.sampleMethod2(); //you will get a message from 'sampleMethod()'
+1

Eval does what you want to do. However, Eval is evil because you should not do what you want.

Why is using the JavaScript eval function a bad idea?

0
source

All Articles