JavaScript Symbol+闭包实现对象的私有属性

99 阅读2分钟

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

0505-1.png

关于闭包(作用域)重提一个知识点

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。