Javascript 是否可以使用字符串从对象调用方法?

Javascript 是否可以使用字符串从对象调用方法?,javascript,jquery,string,methods,eval,Javascript,Jquery,String,Methods,Eval,是否可以使用字符串从对象调用方法 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;

是否可以使用字符串从对象调用方法

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
var elem=$(“#测试”)//
var str=“attr('id')”;
//这就是我想要达到的目标
属性元素(“id”)//测试
//到目前为止我都试过了
elem.str//未定义
元素str()//对象[Object Object]没有方法“str”
var fn=评估值(str)//属性未定义
eval(elem.toString()+'.+str)//意外标识符
//到目前为止我找到的唯一解决办法,
//但这不是我的选择
//因为这段代码在函数中
//因此,元素和方法调用
//如果你被录取了,我就不知道了
//它们是什么
eval($('#test').attr('id')//测试

Eval做你想做的事。然而,Eval是邪恶的,因为你不应该做你想做的事


更新

这是我最后的工作答案:
在控制台中运行此代码之后

theMethod = 'attr("id","foo")'.match(/^([^(]+)\(([^)]*)\)/);
jQuery('#post-form')[theMethod[1]].apply(jQuery('#post-form'),JSON.parse('['+theMethod[2]+']'));
post-form元素现在有了一个新的ID,没有任何问题。这适用于接受多个参数、单个参数或根本不接受参数的方法。概述:

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+']'));
这是我能想到的最安全、最可靠的方法,真的


无论你做什么,都不要使用EVAL:

这与任何对象使用的基本原则相同(记住,函数在JS中都是独立的对象,而jQuery对象也是对象)。这意味着可以使用与属性完全相同的方式访问方法:

$('#foo').attr('id') === $('#foo')['attr']('id');
所以只要把字符串分开,像使用对象属性一样使用方法名,就可以了

只要记住:当你只有一把评估锤时,一切看起来都像你的拇指。
布伦丹·艾奇


如果有可能将多个参数传递给任何方法,您也可以按自己的方式来解决(我认为-好吧:逻辑决定了,但现在已经很晚了,逻辑已经被杜松子酒打得很糟糕了):


这会将处理的任何元素/对象的方法应用于自身,因此不会更改调用方上下文(
仍将指向该方法中的对象),并且它会传递一组参数,这些参数将传递给被调用的方法。

您应该使用以下方法之一:

  • 申请

    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()'

您是否尝试过警报(elem+'.'.+str)@AshirvadSingh-显示
[object object].attr('id')
检查此项:@Aby-是的,我看到了。这适用于从字符串调用函数,但我希望从字符串调用对象的方法。您无法可靠地在逗号上拆分参数,因为参数中可能有其他逗号
'func(问候(“Elias”,“嗨,你好吗”),/(.*),.*/)”
很公平,这只是一个黑暗中的疯狂尝试,需要做一点工作,而且我可以写一个表达式来可靠地分解论点,但喝的更少。不过,您可以只
JSON.parse('[“foo”,“bar”]')
在这种情况下:
elem,theMethod[2]。apply(elem,JSON.parse('['+theMethod[2]+'])很好用,不是吗?哈,想想看,这比分开还要好。。。我正在编辑我的答案!杜松子酒万岁!JSON数据只代表可能出现的语法的一小部分。像
未定义
、标识符、正则表达式、匿名函数和函数调用之类的东西会破坏它。我认为这将归结为解析JavaScript,或者使用
eval
。您从一个字符串开始,该字符串包含一个函数定义/声明,然后需要将其作为参数传递给jQ方法,这种可能性有多大?如果这个问题的答案很简单,那么我很抱歉,你解决问题的方式有问题。。。但这正是我对此的感受,是的,然后评估变得非常必要。虽然您正跳入eval最危险的用法:eval-ing创建新函数。。。Ouch当你在这个站点上时,在你的控制台
eval('$=function(){return null;}')
中键入这个,然后检查通过杀死jQuery丢失了什么功能…以及从格式为
.attr('arg','arg')
?that[“sampleMethod”]的字符串开始的位置;我想你误解了。OP正在寻找一种无需评估的方法来从字符串开始,比如
var someStr='setAttr(“id”,“foobar”)
并使用它调用jQuery对象上的
setAttr
方法并正确传递参数,您的方法不会这样做另一件事:为什么要使用
that
,而不是this?我不认为在这两种方法中,
这个
将引用
示例
对象有什么意义,我同意,在特定情况下“那”是多余的。例如,当“Sample”类包含jQuery事件绑定($(文档)。单击(function(){…});)调用“Sample”类的公共函数时,这是实际的。
theMethod = theMethod.match(/^([^(]+)\(([^)]+)\)$/);
//["attr('id','foo')", "attr", "'id','foo'"] --> regex must now match quotes, too
elem.theMethod[1].apply(elem,JSON.parse('['+theMethod[2]+']'));
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()'