在函数内部调用函数

时间:2011-12-04 22:58:27

标签: javascript oop coding-style code-reuse

当我编写代码时,我会尝试将所有内容划分为函数(方法,如果您愿意)。函数X做东西X,Y做Tuff Y和就像方法X做东西X,Y& ž!这给了我更多可重用的代码。我喜欢。 :)

让我们来看看这段代码:

var user = {
  users: [],
  userCount: 0,
  addUser: function(user) {
    (this.users).push(user);
  },
  incrementCount: function() {
    ++this.userCount;
  }
}

var user = { // 2nd example.
  users: [],
  userCount: 0,
  addUser: function(user) {
    (this.users).push(user);
    ++this.userCount;
  }
}

(它在JavaScript中,但这里的语言不是必需的。)

在我看来,第二个示例将更容易,并且更安全可以用于API用户。 忘记拨打user.incrementCount()很容易。你怎么看?第二个例子自动完成。

那么如何找到平衡?关于在函数内调用函数的任何最佳实践?

感谢您阅读本文。

修改

刚才我想到了这一点:

var user = {
  users: [],
  userCount: 0,
  addUser: function(user) {
    (this.users).push(user);
    this.incrementCount();
  },
  incrementCount: function() {
    ++this.userCount;
  }
}

4 个答案:

答案 0 :(得分:5)

在JS中有点不同,因为在使用对象文字表示法时,没有办法让函数真正变为私有,但是......

这就是您希望对象向其消费者公开的API。您是否希望API的使用者能够与添加用户分开增加计数?如果是这样的话:

{ addUser: /* snip */, incrementCount: /* snip */ }

否则:

{ addUser: /* snip */, _incrementCount: /* snip */ }
// or just
{ addUser: /* snip */ }

在这种特殊情况下,我强烈建议不要存储任何单独的计数,因为users数组已经为你做了。

var user = {
  _users: [],
  addUser: function(user) {
      this._users.push(user);
  },
  getUserCount: function () {
      return this._users.length;
  }
  // and if you need to expose the users array directly,
  , getUsers: function () {
      return this._users;
  }
}

答案 1 :(得分:3)

就个人而言,我认为您甚至不应该通过API公开这些内容。此外,仅使用users.length将更容易并且(至少在JavaScript中)更直观。

最终,我认为保持界面非常简单通常是件好事。抽象是一件好事。如果我使用其他人的库,我会非常失望地得知我应该手动增加该值。

<强>更新

我认为还有一件事值得一提:

通过让您的代码在内部维护状态并保持API简单,您不仅可以使用户的生活更轻松,而且还可以防止滥用(在可能的范围内)。很容易想象一个人不正确地使用这种增量方法的情况,结果就会破坏它。

答案 2 :(得分:1)

你说“功能A做A-Stuff”是对的。 但是:一个处理数据的函数,从外部隐藏(或多或少),应该用数据做的事情(例如添加用户)并使shure,数据仍然是正确的(例如,如果你有一个用户列表,增加Usercounter使其成为shure它总是正确的)。 如果你想离开,希望你的API的用户为你做这个东西,它总是不舒服。

想象一下,您向用户列表添加了更多功能(例如,告诉用户它已添加到列表中,将用户存储在二叉树中等等),并且您必须执行所有组织来自你职能之外的东西,那里有什么好处?

答案 3 :(得分:1)

我知道你只是想让示例代码成为一个简单的例子,但是像计数或长度变量一样,我想不出为什么我想让它独立于添加或删除项目的功能。使用该对象时,您不希望每次添加时都调用add() increment()方法,并且真的不要我希望能够在没有另一个的情况下做一个,或者你的对象最终处于无效状态。

所以我从来没有做过第一种方式,当然你在编辑中添加的方式更糟糕。让你的函数相互调用没有错,但在你的例子中,我希望增量函数是私有的。

最好将count变量设为私有,只允许通过函数检索它并通过add / remove函数设置(尽管你只需返回users.length就不需要计数变量)。具有立即执行的匿名函数的以下模式允许您拥有私有变量和函数,并且您只返回包含公共函数的对象。公共函数仍然可以访问私有变量/函数,但不能从外部访问私有函数。

var user = (function() {
   var users = [],    // private variables
       private1,
       private2;

   function privateFunction1() { /* do something */ }

   return {
      getUserCount : function() {
                       return users.length;
                     },
      addUser:       function(user) {
                       users.push(user);
                       // return index of new user
                       return users.length - 1;
                     },
      getUser :      function(userIndex) {
                       return users[userIndex];
                     },
      someFunc :     function(someParam) {
                       return someParam + privateFunction1();
                     }
   }
})();

user.addUser("Fred");
user.addUser("Mary");
console.log(user.getUserCount()); // 2
console.log(user.getUser(1));     // Mary