在封装上揭示模块与对象字面模式

我通常做每个function的组件,说我有ABCfunction,我会创build下面的JS

var AbcComponent = (function(){} var initialize = function(){ }, privateMethod1 = function(){ }; return {init:initialize} )(); 

并包含在app.js中,使用AbcComponent.init(); 。 几天前,我用对象字面模式准备好面向对象,我怀疑自己的写作风格。

字面模式如何封装范围,因为JavaScript是function范围?

所有需要真正私有数据的模块模式必须固有地使用一个IIFE来维护自己的私有范围。 即使是对象文字模块模式也使用这个。 查看一些模块模式的比较,

您可以用对象文字以几种方式存储伪私有数据:

按照惯例,以_下划线开头的属性被理解为是世界其他地方的禁区。

 { _privateBar : 1 publicFoo : 4, } 

或者,您可以使用符号 。

 const privateBar = Symbol('private'); myModule[privateBar] = 1; myModule.publicFoo = 4; 

使用后者,只有对privateBar符号对象的引用才能从privateBar中获得1的值。 不,你不能用myModule[Symbol('private')]得到它,因为符号是唯一的, Symbol('private') === Symbol('private')false

不幸的是,他们决定添加Object.getOwnPropertySymbols() ,所以一个对象的符号不是真正的私有的,不适合保护数据免受恶意活动的侵害。

但是,在实践中,您执行的大多数操作( for of循环等)将不会触及符号。 因此它是下划线_惯例的一个很好的替代品。 但有时甚至有更好的方法 ,比如使用WeakMap 。

通过使用ES6,我们实际上可以避免由于词法范围的限制而导致的IIFE的轻微开销。

 const myModule = {}; { const privateBar = 1; myModule.publicFoo = 4; }