使用自执行函数和call方法
JavaScript使用原型,没有像面向对象语言那样的类(或者说方法)。JavaScript开发人员需要以JavaScript的思维方式进行思考。
维基百科引用:
与许多面向对象的语言不同,函数定义和方法定义之间没有区别。相反,在函数调用时出现了区别;当一个函数作为对象的方法被调用时,该函数的本地this关键字会绑定到该对象上。
使用自执行函数和call方法来调用私有“方法”的解决方案:
var MyObject = (function () {
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();
myObject.privateFun(">>");
call function允许我们使用适当的上下文(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();
myObject.privateFun(">>");
(新!)未来JavaScript版本中的本地私有方法
TC39 JavaScript类的私有方法和getter/setter 提案处于第3阶段。这意味着很快,JavaScript将原生支持私有方法!
请注意,JavaScript私有类字段 已经存在于现代JavaScript版本中。
以下是一个示例,展示了如何使用它:
class MyObject {
#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中实现(stage 0)。
export default class MyObject {
constructor (foo) {
this._foo = foo;
}
publicFun () {
return this::privateFun(">>");
}
}
function privateFun (prefix) {
return prefix + this._foo;
}
class
是因为这个问题旧了。现在存在一种实验性的功能,可以使用#
作为前缀来允许私有方法,但截至2020-08-19,并不是所有浏览器都支持该功能。请参见: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields - Josh Desmond