【问题描述】:

如何检查对象内部是否存在私有函数?

var myObj = function(){
    var myFunc = function(){};

    var init = function(){
        //has myFunc been defined?
    }
}

我知道我可以做到:

if (typeof myFunc == 'function') { 
    //myFunc exist
}

但这是在检查全局范围。
如何将其限制在我的对象范围内?

这是我需要的最简化的案例:

var myComponent = function () {
    var exportExcel = function () {

    };
    this.export = function (type) {
        if('export'+type is a private function in this scope){
            window["export"+type]()//but in local scope;
        }
    }
};

这是我现在的工作:

var myComponent = function () {
    var Exports = {
        Excel: function () {

        }
    };

    this.export = function (type) {
        if (Exports.hasOwnProperty(type)) {
            Exports[type]();
        } else {
            alert('This Export type has not been implemented Yet ! or it never will ... how knows? well i don\'t ...');
        }
    }
};

【问题讨论】:

  • 为什么不添加一个公共方法来检查私有方法是否存在?
  • 它不是检查全局范围,而是首先检查本地,这就是词法范围的工作方式。这看起来像一个 XY 问题......你为什么要这样做?现实世界的应用是什么?
  • 你是怎么调用 init 的?
  • 你可以这样做 if (myFunc && myFunc !== window.myFunc) 也许?
  • @Exlord:我仍然认为这是一个 XY 问题。您正在考虑使用 PHP,但使用 JavaScript 编写代码。我所说的真实世界是指您要解决的问题的描述是什么?

标签: javascript function object private


【解答1】:

根据给出的额外信息,最实用的模式是您所说的“临时解决方法”:将函数保存在私有对象中,按类型键入。

var myComponent = function () {
    var exporters = Object.create(null, {
        "Excel": function () {
            // do magic export here
        }
    });

    this.export = function (type) {
        if (type in exporters) {
            // defined locally
            return exporters[type].call(this); // binding is optional
        } else {
            // no export for you!
        }
    }
};

这可以防止两件事:

  1. 通过字符串组合引用函数,
  2. 查询全局范围(或​​者实际上是您的组件和全局范围之间的任何范围)。

这可能不是您的设计原则,您可以进一步扩展此代码以允许添加/删除导出器。

【问题讨论】:

  • @Exlord 啊;好吧,这恰好也是最合理的解决方案 :)
【解答2】:

你可能已经注意到了:

function myFunc () {};

function myObj () {
    function init () {
        if (myFunc) // passes
    };
}

你可以作弊一点:-|

function myObj () {
    var isdef = { myFunc: true };
    function myFunc () {};
    function init () {
        if (isdef.myFunc) // do something
    };
}

我想知道为什么有人会这样做。

【问题讨论】:

  • 嗯...他想检查它是否存在...这意味着他不能只更改这行代码^^
  • @DenysSéguret 只要你可以编辑 init 的范围,你应该可以编辑 myObj 的范围:-|
  • 我已经有 :D ,不是这样,但我在私有对象中定义了我的私有函数并检查了它的 hasOwnProperty :D
  • @Exlord hasOwnProperty 在这种情况下无能为力,因为您从未定义任何属性:-)