如何在JavaScript模块模式中的私有函数中调用公共函数 [英] How do I call a public function from within a private function in the JavaScript Module Pattern

查看:191
本文介绍了如何在JavaScript模块模式中的私有函数中调用公共函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

例如,在以下代码中,

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

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

已问过这个问题两次

This question has been asked twice before, with a different accepted answer for each.

  1. 在返回对象之前保存对返回对象的引用,然后使用该引用访问公共方法.请参阅 answer .
  2. 在闭包中保存对public方法的引用,并使用该引用访问public方法.请参见 answer .
  1. Save a reference to the return object before returning it, and then use that reference to access the public method. See answer.
  2. Save a reference to the public method in the closure, and use that to access the public method. See answer.

尽管这些解决方案有效,但从OOP的角度来看,它们并不令人满意.为了说明我的意思,让我们对每种解决方案的一个雪人进行具体实现,然后将它们与简单的对象文字进行比较.

While these solutions work, they are unsatisfactory from an OOP point of view. To illustrate what I mean, let's take a concrete implementation of a snowman with each of these solutions and compare them with a simple object literal.

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

Snowman 1: Save reference to return object

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:保存对公共功能的引用

Snowman 2: Save reference to public function

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

我们可以看到这三个功能相同,并且具有完全相同的公共方法.

We can see that the three are identical in functionality and have the exact same public methods.

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

If we run a test of simple overriding, however

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失败了.

如果我们对原型覆盖进行测试,

If we run a test of prototype overriding,

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都失败了.

we see that both #1 and #2 fail.

这是一个非常丑陋的情况.仅仅因为我选择了以一种或另一种方式重构代码,返回对象的用户就必须仔细研究我如何实现一切以弄清楚他/她是否可以覆盖我的对象的方法并期望它能正常工作. !尽管这里的观点有所不同,但我个人的观点是正确的覆盖行为是简单对象文字的行为.

This is a really ugly situation. Just because I've chosen to refactor my code in one way or another, the user of the returned object has to look carefully at how I've implemented everything to figure out if he/she can override my object's methods and expect it to work! While opinions differ here, my own opinion is that the correct override behavior is that of the simple object literal.

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

So, this is the real question:

是否可以从私有方法中调用公共方法,以使生成的对象在覆盖行为方面像对象文字一样?

推荐答案

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

You can use this to get the object your privileged method greet was called on.

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

Then, you can pass that value to your private method _sayHello, e.g. using call, apply, or as an argument:

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模块模式中的私有函数中调用公共函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆