使用自调用函数和调用
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版本中的原生私有方法
TC39私有方法和JavaScript类的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;
}