【问题标题】:Data Hiding in JavascriptJavascript中的数据隐藏
【发布时间】:2012-07-17 15:27:00
【问题描述】:

在 Java 编程语言中,private 关键字用于隐藏数据 - 标记为私有的字段或方法在类或子类之外不可见。

这是如何在 javascript 中实现的?

【问题讨论】:

  • 私人领域是通过显着的自虐来实现的。
  • 与大多数与 JavaScript 相关的东西一样,Douglas Crockford 也有一些有趣的 ideas about private members 在该语言中。

标签: javascript oop


【解决方案1】:

在 JavaScript 中的标准方式是使用 Module Pattern 如下所示..

var testModule = (function () {

    var myPrivateVar = 0;

    var myPrivateMethod = function (someText) {
        console.log(someText);
    };

    return {

        myPublicVar: "foo",

        myPublicFunction: function (bar) {
            myPrivateVar++;
            myPrivateMethod(bar);
        }

    };
})();

用法:在上面的代码中,返回一个对象,其中包含一个变量(myPublicVar)和一个函数(myPublicFunction)。在此函数内部,您可以访问内部变量 (myPrivateVar) 和内部函数 (myPrivateMethod),但不能从外部访问。

var mod = new testModule();
mod.myPublicFunction(param);

【讨论】:

  • 效果很好,由 Douglas Crockford 本人推荐 :)
  • 您能否解释一下您的代码中发生了什么,以及这究竟如何涵盖隐藏在 javascript 中的数据 - 谢谢
  • 查找“javascript 闭包”以了解如何在公共范围之外维护数据。另一个函数内部的任何函数都会创建一个闭包。内部功能可以“记住它周围的东西”。上面的例子演示了一个用 () 立即执行的函数,从而返回一些对名为“testModule”的新对象的内部引用。
  • "testModule" 是一个对象,但不是一个函数。如何使用“新 testModule()”
【解决方案2】:

这一切都是通过范围界定来实现的。

var MYCLASS = function(){

     var priv_var = 0; //private var

     this.addToVar = function(){
         priv_var++;
     }

     this.showVar = function(){
         return priv_var;
     }

}

var mc = new MYCLASS;

mc.addTovar();
alert(mc.showVar()); //"1"

【讨论】:

    【解决方案3】:
    "use strict";
    
    var Person = function (fName, lName) {
    
        var firstName = fName || "AN", lastName = lName || "Other";
    
        var fullName = function () {
            return firstName + ' ' + lastName;
        };
    
        return {
            setName: function (fName, lName) {
                firstName = fName;
                lastName = lName;
            },
    
            getFullName: function() {
                return fullName();
            }
        };
    
    }
    
    var p = new Person("Your", "name");
    
    console.log(p.getFullName());
    

    【讨论】:

      【解决方案4】:

      这是一个您可能会喜欢的简单 API。它具有三个功能:Key(构造函数)、KeepSecret、FetchSecret。

      您可以做的是拥有一个带有秘密守护者的对象作为属性。然后对象可以“携带”数据,但是访问对象但不知道密钥的代码无法访问隐藏的数据。

      /**
       * Example usage:
       *
       * Create a key
       *
      var mykey = Key();
      
       *
       * Keep a secret
       *
      var mykeeper = KeepSecret(mykey, 42);
      
       *
       * Fetch the secret
       *
      var answer = FetchSecret(mykey, mykeeper);
      
       *
       * 'answer' will then contain 42
       */
      
      (function(Namespace, Code) { return Code(Namespace); })(
          /* Choose the namespace for Key, KeepSecret, FetchSecret */
          this,
      
          function(Namespace) {
      
      /*
       * Simply so that we can use "Key" as both a type-name
       * and a parameter-name
       */
      var ikey;
      
      /** Constructor for a key */
      function Key() {
          if (!(this instanceof Key))
            return new Key();
        }
      
      /* Same key constructor */
      ikey = Key;
      
      /**
       * Hide a secret using a key
       *
       * @param Key
       *   The key to lock away the secret with
       *
       * @param Secret
       *   The secret to be locked away
       *
       * @return
       *   A function which hides the secret inside
       */
      function KeepSecret(Key, Secret) {
          /* The function can access itself */
          var closure;
      
          if (!(Key instanceof ikey))
            throw "KeepSecret: Invalid key";
      
          closure = function(key) {
              /* If we were not passed the key, authenticate */
              if (key !== Key) {
                  Key.keeper = closure;
                  return;
                }
      
              /* The caller knew the key, so reveal the secret */
              return Secret;
            }
          return closure;
        }
      
      /**
       * Use a key and a function to reveal the secret that function keeps
       *
       * @param Key
       *   The key for unlocking the secret
       *
       * @param Keeper
       *   The function keeping the secret
       *
       * @return
       *   The secret, if the key unlocks it
       */
      function FetchSecret(Key, Keeper) {
          /* Tracks authentication */
          var closure;
      
          if (!(Key instanceof ikey) || !(Keeper instanceof Function))
            throw "FetchSecret: Invalid parameter(s)";
      
          /* Ask the keeper to authenticate */
          Keeper();
      
          /* Note the authenticated function */
          closure = Key.keeper;
      
          /* Clear the authentication */
          delete Key.keeper;
      
          /* Did the keeper prove that they know the key? */
          if (closure !== Keeper)
            /* No */
            return;
      
          /* They know the key.  Show we know the key, too */
          return closure(Key);
        }
      
      Namespace.Key = Key;
      Namespace.KeepSecret = KeepSecret;
      Namespace.FetchSecret = FetchSecret;
      return true;
      
        });
      

      【讨论】:

        猜你喜欢
        • 2016-05-15
        • 1970-01-01
        • 2011-11-02
        • 1970-01-01
        • 2022-01-21
        • 2013-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多