0

例如:

function foo() {

  var bar = "", obj = {};

  obj.change = function(key, val){
    // how change bar?
    return obj;
  }

  return obj;
}

foo().change("bar", "foo");

如果bar将是obj.bar答案obj[key] = val;,那么bar将是公开的。我希望能够以bar类似 jQuery 的样式进行设置,但不公开。

4

4 回答 4

2

您可以将代码封装在 IIFE(立即调用的函数表达式)中,并创建两个对象,一个用于public成员,另一个用于private成员。通过使用闭包,您可以保持private私密,并公开您需要的内容。

var foo = (function() {

  var public = {},
      private = {
        name: 'John'
      };

  public.change = function(key, val) {
    private[key] = val;
  };

  public.say = function() {
    return 'Hello '+ private.name;
  };

  return public;
}());

console.log(foo.say()); //=> "Hello John"

foo.change('name', 'Mike');
console.log(foo.say()); //=> "Hello Mike"

阅读有关显示模块模式的更多信息。

于 2013-09-02T20:18:01.390 回答
0

您不能从闭包范围内更改具有任意名称的变量,但是。需要将它们放在某个对象中以供参考:

function foo() {
  var data = {},
      obj = {};
  obj.change = function(key, val){
    if (arguments.length === 2) {
      data[key] = val;
      return obj
    } else if (arguments.length === 1) {
      return data[key];
    }
  }
  return obj;
}

foo().change("bar", "foo")
于 2013-09-02T20:15:25.073 回答
0

目前 bar 是私有的,因为它在 foo 函数的范围内。无法从外部访问。一个简单的解决方案是保留一个包含所有密钥的私有数组列表。

function foo() {
 //private variables. Thanks to closure.
 var _privateKeys = [],
     obj = {};

 obj.change = function(key, val){
 if(arguments.length == 2)
   _privateKeys[key]=val;
 return obj;
 }

 return obj;
}

foo().change("bar", "foo");
于 2013-09-02T20:20:00.443 回答
0

最终代码受, answer 和answer 启发:elclanrs answerthisthis

(function(window) {
    var private = {
        name: 'John'
    };
    function foo() {
      // if without `new` foo().change() will not work :(
      // but foo.change() will
      if (!(this instanceof foo))
          return new foo();
      return this;
    }
    foo.change = function(key, val) {
      private[key] = val;
      foo.say();
      return this;
    };
    foo.say = function() {
      console.log('Hello '+ private.name);
      return this;
    }; // prototype used for foo().say() and foo().change()
    foo.prototype.change = function(key, val) {
      return foo.change(key, val);
    };
    foo.prototype.say = function() {
      return foo.say();
    };
    window.foo = foo;
})(window);

foo.say().change('name', 'Ben'); 
// => "Hello John" => "Hello Ben"
foo().change('name', 'Mike').change('name', 'Sam');
// => "Hello Mike" => "Hello Sam"

jsfiddle.net

于 2013-09-03T03:19:20.997 回答