从属性字符串运行函数

Running function from attribute string

本文关键字:函数 运行 字符串 从属性      更新时间:2023-09-26

我有一个这样的选择菜单:

<select name="moduleGroup">
    <option data-function="getListing('pages')">Pages</option>
</select>
Javascript

function getListing(s) {
    console.log(s);
}
$('select').on('change', function() {
    var func = $(this).find('option:selected').attr('data-function');
    [func]();
});

我也试过,$[func]();, $('body')[func]();

我读了很多关于同样问题的帖子,但是没有一个帮助我:这里,这里

我肯定我做错了什么,但是有人能给我指个方向吗?

最简单的方法是像这样调用eval():

$('select').change(function() {
    var func = $(this).find('option:selected').attr('data-function');
    eval(func);
});

小提琴:http://jsfiddle.net/gywzb/4/

但是全世界都认为这是一个不好的做法。正如我最喜欢的linter所说,"eval()是邪恶的。"它给你带来了许多令人讨厌的安全漏洞(特别是当你维护应用程序时,事情会从你最初编写它的方式发生变化),而且性能也很糟糕。幸运的是,有更好的方法。

首先,我要稍微分解一下数据属性,这样就不会有一个包含函数名和参数的属性,而是有两个属性:一个用于函数名,另一个用于参数。

<select name="moduleGroup">
    <option data-function="getListing" data-parameter="pages">Pages</option>
</select>
其次,我们将创建一个"类"来包装你的函数,如下所示:
var MyClass = function() {
}
MyClass.prototype = {
    getListing: function(s) {
        console.log(s);
    }
};

最后,下面是你如何使用上面的修改来调用你的函数:

$('select').on('change', function() {
    var func = $(this).find('option:selected').attr('data-function');
    var param = $(this).find('option:selected').attr('data-parameter');
    var myInstance = new MyClass();
    var funcRef = myInstance[func];
    funcRef.call(myInstance, param);
});

这是整件事:http://jsfiddle.net/7CwH4/2/

当你使用。call方法来调用你的函数时,神奇的事情发生了。.call()方法的第一个参数是函数将其视为this对象的对象。.call的下一个参数是该函数的第一个参数。(如果你的函数有更多的参数,.call的第三个参数将是函数的第二个参数,等等。如果对.call感到困惑,请参阅MDN文档。)

如果需要传递比字符串更复杂的数据作为参数,可以将其作为JSON字符串放在data-parameter属性中,然后使用$。在将参数传递给函数之前,将其转换为对象:

// If your data-parameter attribute contained a JSON string.
$('select').on('change', function() {
    var func = $(this).find('option:selected').attr('data-function');
    var param = $(this).find('option:selected').attr('data-parameter');
    var paramObj = $.parseJSON(param);
    var myInstance = new MyClass();
    var funcRef = myInstance[func];
    funcRef.call(myInstance, paramObj);
});