JavaScript Symbol+闭包实现对象的私有属性
写在前面: 1.class person{}:class语法糖后面的括号内部属于一个块级作用域。 2.class中的this是运行时绑定的,class必须用new调用,因此this绑定到new产生的对象上
①闭包的作用:通过作用域链机制,把私有属性封闭在深层作用域里(认为作用域链只能向上访问),使得外层作用域”不知道“私有属性的名字。在定义私有属性名变量所处的作用域中深层定义class类,此时class类属于更深层的块级作用域,可以访问到上一层作用域定义的私有属性名。最后在向最外层返回class类,使得最外层new调用的时候利用constructor给私有属性赋值。 ②Symbol的作用:Symbol是唯一且不可变的原始数据类型,对象的属性只能为String或Symbol,其中Symbol作为属性不可被for...in.../Object.keys()/Object.getOwnPropertyNames()等方法遍历,只能通过Object.getOwnPropertySymbols()遍历,提高了安全性
具体实现
const person = (()=>{
const _name=Symbol('name');
const _age=Symbol('age');
class myPerson{
constructor(name,age){
this[_name]=name;
this[_age]=age;
}
getDetail(){
return (this[_name]+this[_age]+'detail');
}
}
return myPerson;
})()
let personNow = new person('Jack',21);
console.log(personNow.getDetail());//Jack21detail
关于闭包(作用域)重提一个知识点
for (var i = 0; i < 5; i++) {
(function(j) {
setTimeout(function() {
console.log(j); // 输出 0,1,2,3,4
}, 100);
})(i);
}
如果这里不用IIFE创建块级作用域,那么setTimeout的回调函数就会在for的块级作用域里寻找i变量,由于i是var定义的全局变量,此时i=4,所以会输出4,4,4,4,4。使用IIFE创建块级作用域后,setTimeout处于块级作用域内,块级作用域使用i产生i的闭包,保留每个块级作用域中i的值,输出0,1,2,3,4。