JavaScript 私有方法

新手上路,请多包涵

要使用公共方法创建 JavaScript 类,我会执行以下操作:

function Restaurant() {}

Restaurant.prototype.buy_food = function(){
   // something here
}

Restaurant.prototype.use_restroom = function(){
   // something here
}

这样我班的用户可以:

var restaurant = new Restaurant();
restaurant.buy_food();
restaurant.use_restroom();

如何创建一个可以由 buy_fooduse_restroom 方法调用但不能由该类的用户在外部调用的私有方法?

换句话说,我希望我的方法实现能够做到:

Restaurant.prototype.use_restroom = function() {
   this.private_stuff();
}

但这不应该工作:

var r = new Restaurant();
r.private_stuff();

如何将 private_stuff 定义为私有方法,以便这两个都成立?

我已经阅读了 Doug Crockford 的 文章几次,但似乎“私有”方法不能被公共方法调用,而“特权”方法可以在外部调用。

原文由 Wayne Kao 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

你可以这样做,但缺点是它不能成为原型的一部分:

 function Restaurant() {
 var myPrivateVar;

 var private_stuff = function() { // Only visible inside Restaurant()
 myPrivateVar = "I can set this here!";
 }

 this.use_restroom = function() { // use_restroom is visible to all
 private_stuff();
 }

 this.buy_food = function() { // buy_food is visible to all
 private_stuff();
 }
 }

原文由 17 of 26 发布,翻译遵循 CC BY-SA 4.0 许可协议

使用自调用函数并调用

JavaScript 使用 原型 并且没有像面向对象语言那样的类(或相关方法)。 JavaScript 开发人员需要用 JavaScript 思考。

维基百科引述:

与许多面向对象的语言不同,函数定义和方法定义之间没有区别。相反,区别发生在函数调用期间;当函数作为对象的方法被调用时,函数的局部 this 关键字将绑定到该对象以进行该调用。

使用 自调用函数调用函数 调用私有“方法”的解决方案:

 var MyObject = (function () {

  // Constructor
  function MyObject(foo) {
    this._foo = foo;
  }

  function privateFun(prefix) {
    return prefix + this._foo;
  }

  MyObject.prototype.publicFun = function () {
    return privateFun.call(this, ">>");
  }

  return MyObject;

}());

 var myObject = new MyObject("bar");
myObject.publicFun();      // Returns ">>bar"
myObject.privateFun(">>"); // ReferenceError: private is not defined

调用函数 允许我们使用适当的上下文调用私有函数( this )。

使用 Node.js 更简单

如果您使用的是 Node.js ,则不需要 IIFE ,因为您可以利用 模块加载系统

 function MyObject(foo) {
  this._foo = foo;
}

function privateFun(prefix) {
  return prefix + this._foo;
}

MyObject.prototype.publicFun = function () {
  return privateFun.call(this, ">>");
}

module.exports= MyObject;

加载文件:

 var MyObject = require("./MyObject");

var myObject = new MyObject("bar");
myObject.publicFun();      // Returns ">>bar"
myObject.privateFun(">>"); // ReferenceError: private is not defined

(新!)未来 JavaScript 版本中的原生私有方法

JavaScript 类提案的 TC39 私有方法和 getter/setter 是第 3 阶段。这意味着很快,JavaScript 将在本地实现私有方法!

请注意,现代 JavaScript 版本中已经存在 JavaScript 私有类字段

这是一个如何使用它的例子:

 class MyObject {

  // Private field
  #foo;

  constructor(foo) {
    this.#foo = foo;
  }

  #privateFun(prefix) {
   return prefix + this.#foo;
  }

  publicFun() {
    return this.#privateFun(">>");
  }

}

您可能需要 JavaScript 转译器/编译器 才能在旧的 JavaScript 引擎上运行此代码。

PS:如果您想知道为什么 # 前缀, 请阅读本文

(已弃用)带有绑定运算符的 ES7

警告:绑定运算符 TC39 命题即将失效 https://github.com/tc39/proposal-bind-operator/issues/53#issuecomment-374271822

绑定运算符 :: 是一个 ECMAScript 提案在 Babel第 0 阶段)中实现。

 export default class MyObject {
  constructor (foo) {
    this._foo = foo;
  }

  publicFun () {
    return this::privateFun(">>");
  }
}

function privateFun (prefix) {
  return prefix + this._foo;
}

原文由 Yves M. 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题