在封装上揭示模块与对象字面模式
我通常做每个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; }