javascript - 如何从 JavaScript 模块模式中的私有(private)函数中调用公共(public)函数

标签 javascript module-pattern

如何从 JavaScript 模块模式中的私有(private)函数调用公共(public)函数?

例如,在下面的代码中,

var myModule = (function() {
    var private1 = function(){
        // How to call public1() here?
        // this.public1() won't work
    }

    return {
        public1: function(){ /* do something */}
    }
})();

这个问题有人问过twice before ,每个都有不同的可接受答案。

  1. 在返回之前保存对返回对象的引用,然后使用该引用访问公共(public)方法。参见 answer .
  2. 在闭包中保存对公共(public)方法的引用,并使用它来访问公共(public)方法。参见 answer .

虽然这些解决方案有效,但从 OOP 的 Angular 来看它们并不令人满意。为了说明我的意思,让我们用这些解决方案中的每一个来具体实现一个雪人,并将它们与一个简单的对象字面量进行比较。

雪人 1:保存对返回对象的引用

var snowman1 = (function(){
  var _sayHello = function(){
    console.log("Hello, my name is " + public.name());
  };

  var public = {
    name: function(){ return "Olaf"},
    greet: function(){
      _sayHello();
    }
  };
  return public;
})()

雪人 2:保存对公共(public)函数的引用

var snowman2 = (function(){
  var _sayHello = function(){
    console.log("Hello, my name is " + name());
  };
  var name = function(){ return "Olaf"};

  var public = {
    name: name,
    greet: function(){
      _sayHello();
    }
  };
  return public;
})()

雪人 3:对象字面量

var snowman3 = {
    name: function(){ return "Olaf"},
    greet: function(){
      console.log("Hello, my name is " + this.name());
    }
}

我们可以看到这三者在功能上是完全相同的,并且具有完全相同的公共(public)方法。

但是,如果我们运行一个简单覆盖的测试

var snowman = // snowman1, snowman2, or snowman3
snowman.name = function(){ return "Frosty";}
snowman.greet(); // Expecting "Hello, my name is Frosty"
                 // but snowman2 says "Hello, my name is Olaf"

我们看到 #2 失败了。

如果我们运行原型(prototype)覆盖测试,

var snowman = {};
snowman.__proto__ = // snowman1, snowman2, or snowman3
snowman.name = function(){ return "Frosty";}
snowman.greet(); // Expecting "Hello, my name is Frosty"
                 // but #1 and #2 both reply "Hello, my name is Olaf"

我们看到 #1 和 #2 都失败了。

这是一个非常糟糕的情况。仅仅因为我选择以一种或另一种方式重构我的代码,返回对象的用户必须仔细查看我是如何实现所有内容的,以确定他/她是否可以覆盖我的对象的方法并期望它工作!虽然这里的观点不同,但我个人认为正确的覆盖行为是简单对象文字的覆盖行为。

所以,这才是真正的问题:

有没有一种方法可以从私有(private)方法调用公共(public)方法,以便生成的对象在覆盖行为方面像对象文字一样?

最佳答案

您可以使用 this 获取您的特权方法 greet 被调用的对象。

然后,您可以将该值传递给您的私有(private)方法 _sayHello,例如使用 callapply 或作为参数:

var snowman4 = (function() {
    var _sayHello = function() {
        console.log("Hello, my name is " + this.name);
    };
    return {
        name: "Olaf",
        greet: function() {
            _sayHello.call(this);
        }
    };
})();

现在你可以做

var snowman = Object.create(snowman4);
snowman.greet(); // "Hello, my name is Olaf"
snowman.name = "Frosty";
snowman.greet(); // "Hello, my name is Frosty"

还有

snowman4.greet(); // "Hello, my name is Olaf"
snowman4.name = "Frosty";
snowman4.greet(); // "Hello, my name is Frosty"

关于javascript - 如何从 JavaScript 模块模式中的私有(private)函数中调用公共(public)函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32059222/

相关文章:

javascript - 如何获取数组中所有出现的相同值的索引?

javascript - 如何使用 Node js 将图像和 javascript 文件发送到浏览器

php - onclick 选项卡时发生不同的事件

javascript - 模块模式内的 Google 图表

javascript - 您可以将多个文件缩小为一个文件吗?

javascript 显示模块模式扩展建议

javascript - 通过 javascript api 调用(不是节点)获取 Stripe 客户信息,如何?

javascript - 在网站上以编程方式触发按键

javascript - 是否可以动态访问模块模式中的私有(private)变量?

javascript - 在依赖于 jquery 的 Javascript 中实现模块模式