最近学习了一下ES标准,发现其实有很多直接间接的方法实现一个只读变量,这里总结一下。
1.最直接的是利用对象属性的特性来实现:
1 var obj = {pro1:1}; 2 3 Object.defineProperty(obj, "pro1",{writable: false}); 4 5 obj.pro1 = 2; 6 7 console.log(obj.pro1);//控制台显示1
通过使用Object.defineProperty()函数将obj对象的pro1属性修改为不可写,这样,通过对象的属性形式实现了只读变量。
2.使用对象属性的访问器特性
1 var obj = {pro1:1}; 2 3 Object.defineProperty(obj,"pro1",{ 4 get:function(){ 5 return 1; 6 }, 7 set:function(newValue){ 8 this.pro1 = 1 9 } 10 }); 11 12 obj.pro1 = 2; 13 14 console.log(obj.pro1);//显示1
这里是通过使用Object.defineProperty()设置obj中pro1的访问器属性,无论是给pro1属性设置什么值,pro1的值会设置成1,无论pro1的值是什么也只会返回1。其实感觉只用设置get特性就可以了。
3.“冻结”对象
1 var obj = {a:1}; 2 3 Object.freeze(obj); 4 5 obj.pro1 = 2; 6 7 console.log(obj.pro1);//显示1
这里更厉害了,属性特性什么的完全不管,直接将整个对象“冻结”。Object.freeze()函数在标准中的描述是“Prevents the modification of existing property attributes and values, and prevents the addition of new properties.”。即:阻止修改对象中现有属性的值和特性,并阻止添加新属性。这样,整个对象都成了只读的了,对象里面无论有多少属性,统统都变成只读的了。
4.闭包
前面用了一些看上去很炫酷的方法,提升一下B格,其实要说实现只读,用的最多的当属我大闭包了。
1 var cache = (function(){ 2 var a = 1; 3 4 return function(){ 5 return a; 6 } 7 8 })(); 9 10 console.log(cache());
这里用了闭包的缓存功能,将匿名函数中的a变量缓存起来,间接实现了只读的功能。