簡體   English   中英

在函數內部調用函數

[英]Calling function inside of function

當我編寫代碼時,我會嘗試將所有事物划分為函數(方法,如果您願意的話)。 函數X填充X,Y填充Y, 不像方法X填充X,Y和Z! 這給了我更多可重用的代碼。 我喜歡。 :)

讓我們看一下這段代碼:

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

在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;
  }
}

就個人而言,我什至不建議您通過API公開這些內容。 而且,僅使用users.length會更容易並且(至少在JavaScript中)更直觀。

最終,我認為保持界面非常簡單通常是一件好事。 抽象是一件好事。 如果我使用的是其他人的庫,得知我希望手動增加該值會感到非常失望。

更新:

我認為還有一件事值得一提:

通過使代碼在內部維護狀態並保持API簡單,不僅可以簡化用戶的生活,而且還可以防止濫用(在可能的范圍內)。 容易想象一個場景,有人不正確地使用該增量方法,結果將破壞東西。

您說對了,“函數A做A-材料”是對的。 但是:一種對數據起作用的函數,該函數從外部隱藏(或多或少),應該對數據進行所需的處理(例如,添加用戶),並確保數據仍然正確(例如,如果您有一個用戶列表,請增加Usercounter使其始終正確)。 如果您想讓您的API用戶為您做這些事情,那還是很不舒服的。

想象一下,您向用戶列表中添加了更多功能(例如,告訴用戶已將其添加到列表中,將用戶存儲在二叉樹中,依此類推),並且您必須從在您的功能之外,這樣做的好處是什么?

我知道您只是想將示例代碼作為一個簡單的示例,但是對於諸如count或length變量之類的東西,我想不出為什么我想讓其獨立於函數進行設置的原因)添加或刪除項目。 使用該對象時,您不需要每次add()都必須調用add() increment()方法,並且您確實不希望在沒有其他對象的情況下執行一個操作,否則您的對象最終會陷入無效狀態。

因此,我永遠不會做第一種方法,當然,您在編輯中添加的方法肯定會更糟。 讓您的函數相互調用沒有錯,但是在您的示例中,我還是希望增量函數是私有的。

最好將count變量設為私有,並且只允許通過函數檢索並通過add / remove函數進行設置(盡管當您只需要返回users.length時,甚至不需要count變量)。 帶有立即執行的匿名函數的以下模式使您可以擁有私有變量和函數,並且僅返回包含公共函數的對象。 公共函數仍然可以訪問私有變量/函數,但是私有內容不能從外部訪問。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM