如果需要更改功能中的变量必须是公共的?

时间:2013-09-02 20:06:48

标签: javascript javascript-objects

例如:

function foo() {

  var bar = "", obj = {};

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

  return obj;
}

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

如果barobj.bar,则答案为obj[key] = val;,但bar将公开。我希望能够以类似jQuery的方式设置bar,但不能公开。

4 个答案:

答案 0 :(得分: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"

了解更多信息,了解Revealing Module Pattern

答案 1 :(得分: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")

答案 2 :(得分: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");

答案 3 :(得分:0)

最终代码的灵感来自elclanrs answerthis回答和this回答:

(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