javascript – 从属性字符串运行函数

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

HTML

<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]();

我已阅读有关同一问题的多篇帖子,但没有人帮助我:herehere

我确定我做错了什么,但有人能指出我正确的方向吗?

最佳答案 最简单的方法是调用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 method调用您的函数时,会发生魔力. .call()方法的第一个参数是函数将作为其对象看到的对象. .call的下一个参数是函数的第一个参数. (如果你的函数需要更多的参数,.call的第三个参数将是函数的第二个参数,等等.如果这是令人困惑的话,请参阅MDN documentation .call.)

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

// 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);
});
点赞