【问题标题】:Invoke javascript function from string从字符串调用 javascript 函数
【发布时间】:2012-09-04 11:18:46
【问题描述】:

我的 javascript 模块中有以下代码,但这需要我使这些函数对外界可见。

var mymodule = function() {
    var self = null,
        init = function () { 
            self = this; 
            $('.actionButton').click(function () {
        var worklistId = $(this).data('worklistid'),
            action = $(this).data('action');
        self[action] && self[action](worklistId); //watchout methods marked as not used are used by this invocation
            })
        },
        send = function () {
             // some logic
        },
        finish = function () {
             // some logic
        },
        delete = function () {
             // some logic
        };

    return {
        init: init,
        send: send,
        finish: finish,
        delete: delete
    };
}();

mymodule.init();

所以我唯一想在我的模块中返回的是 init 函数。但是,当我这样做时,我无法调用函数,因为对象(自身)仅包含在外部可见的 init 函数。

return {
    init: init
};

是否有任何解决方案可以像这样调用我的函数而不使它们对外界可见?请不要使用 if else 语句,因为我的工作流程比本示例中的 3 个操作要大。我想让我的模块尽可能的封闭,因为这样可以减少依赖。

更新

这是一个更新的 jsfiddle,其中包含一个建议的解决方案,但这给了我另一个问题。 http://jsfiddle.net/marcofranssen/bU2Ke/

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    这样的事情会起作用:

    var mymodule = function() {
            var self = this;
            init = function () { 
    
                $('.actionButton').click(function () {
            var worklistId = $(this).data('worklistid'), action = $(this).data('action');
            self[action] && self[action](worklistId); //watchout methods marked as not used are used by this invocation
                })
            }
            self.send = function () {
                console.log('send');
            }
            self.finish = function () {
                console.log('finish');
            }
            self.delete = function (item) {
                console.log('delete');
            };
    
        return {
            init: init,
        };
    }();
    
    mymodule.init();​
    

    这是小提琴:

    http://jsfiddle.net/yngvebn/SRqN3/

    通过将self 变量设置为this,在init 函数之外,并将sendfinishdelete 函数附加到self,您可以使用self[action] 语法来自init-function

    【讨论】:

    • 它在我的代码中的 self.send 行上失败,因为 self 未定义。当然,我在声明 var 时已经填满了这个……我错过了什么?
    • 你移动了 var self = this;像我一样到函数的开头?
    • 是的,我做到了。首先,我声明了 self 变量并将其放入其中。然后是一些其他变量,然后是 init,然后是其他函数,通过 self.functionname 它在第一个 self.functionname 失败
    • 你能在 jsfiddle.net 中发布你的代码吗?上面的代码在 jsfiddle 中工作得很好......
    • 啊,因为你使用的是“use strict”,所以你不能乱扔“这个”。我会看看大卫在这里发布的答案:stackoverflow.com/a/12263252/325836
    【解决方案2】:

    是的,有一种简单(但可能有点混乱)的方法可以做到这一点,而无需使函数对全局对象可见:

    var privateFunctions = { deleter: deleter, send: send};
    

    然后,不要使用self[action]();,而是使用privateFunctions[action]();,你就可以开始了。

    请注意,我将delete 更改为deleter,因为delete 是保留关键字...

    【讨论】:

    • 虽然保留关键字不能是变量名,但您仍然可以将其用作属性名。在最坏的情况下,您可以将其声明为字符串:{'delete': ...}
    • 我知道,但我希望,在幸福的一天,保留关键字列表将被清理,同时关键字(如删除)的使用将完全禁止。应该是,恕我直言。此外,将关键字视为禁区以避免任何混淆并不是一个坏习惯
    • 不不,我真的同意 :) 在任何情况下都应该禁止保留关键字。但我个人会使用字符串文字作为键并使用括号表示法而不是重命名键。但这只是个人喜好,这里没有什么要讨论的......最初我想指出,在这里使用delete 不是错误,所以它没有必须被更改,但我同意你的决定。快乐编码! :)
    【解决方案3】:
    var mymodule = function() {
      var self = {},
         init = function () {  
            $('.actionButton').click(function () {
        var worklistId = $(this).data('worklistid'),
            action = $(this).data('action');
        self[action] && self[action](worklistId); //watchout methods marked as not used are used by this invocation
            })
        };
        self.send = function () {
             // some logic
        };
        self.finish = function () {
             // some logic
        };
        self.delete = function () {
             // some logic
        };
        return{
          init:init
        }
    }();
    
    mymodule.init();
    

    这应该工作!

    【讨论】:

      【解决方案4】:

      即使您只返回一个带有 init 属性的对象并动态填充其余对象以便您的模块使用它们,您仍然会在运行时使它们对外部可见。任何想要调试您的模块的人都可以轻松找到它们。

      您仍然可以在运行时创建匿名方法,并且它们也将与它们的实现一起可见。

      【讨论】:

        【解决方案5】:

        在您的代码示例中,“self”到底是什么含糊不清。您应该保持简单,将封装函数用作“私有”方法,并返回可以访问它们的“公共”(或 Crockford 称之为“特权”)函数。

        这是使用私有函数和变量进行单例的 YUI 方式。示例模式:

        var mymodule = (function() {
            var internal = {
                'send': function() {},
                'finish': function() {},
                'delete': function() {}
            };
            return {
                'init': function(action) {
                    // access to internals, f.ex:
                    if ( internal.hasOwnProperty(action) ) {
                         internal[action].call(this); // bring the caller context
                    }
                 }
            };
        }());
        
        mymodule.init('send');
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-02-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-04-19
          • 1970-01-01
          相关资源
          最近更新 更多