ES6 Symbol 实现属性私有化

63 阅读2分钟

    个人网站:aijianli.site/ 可以免费在线制作简历,提供PDF下载,方便快捷。

一、前言

    学习过 java 语言的同学,应该都知道 java 的封装、继承、多态。其中的封装对于类来说,就是提供了修饰符 protected、private 关键字,在开发时可以让类的部分属性和方法不对外提供,只对外提供 public 的方法,属性一般是 private ,对外提供 setter 和 getter 以对属性进行取值和赋值。

    但是在 js 中,并没有提供修饰符让程序员可以将属性私有化。在学习 ES6 的过程中,学习到了 ES6 的 Symbol 类,刚好对公司查询接口的调用方式做了优化见:《ES6代理和反射实现代理方法代理》,为避免此工具类给其他同事使用时暴露类中本该私有化的属性,通过 Symbol 来实现了属性的私有化。

二、具体实现

    其实现过程极为简单,只需在类之前定义部分 Symbol 对象,以 Symbol 对象作为属性的 key 即可,代码如下:

import config from "./config.js";

//使用symbol来作为key,避免外部使用时更改这些属性,导致后续的请求出错
let axiosSym = Symbol("axios");
let vqaUrlSym = Symbol("vqaUrl");
let vqaPrefixSym = Symbol("vqaPrefix");
let interfacePrefixSym = Symbol("interfacePrefix");

class ParentInterface {

    constructor(className, axios) {
        //实现类的类名,根据创建的类的实例对象来从配置文件中取出具体的类的 vqaUrl, vqaPrefix 和 interfacePrefix
        this[axiosSym] = axios;
        let implClass = className;

        let configs = config[implClass];

        if (!configs) throw new Error(`接口类【${className}】缺少配置文件!`)

        this[vqaUrlSym] = configs.vqaUrl;
        this[vqaPrefixSym] = configs.vqaPrefix;
        this[interfacePrefixSym] = configs.interfacePrefix;
    }
}    

    如上代码,axiosSym、vqaUrlSym、vqaPrefixSym、interfacePrefixSym 都是在类之前定义的 Symbol 对象,对于使用 ParentInterface 实例对象的用户来说是不可见的,因此,也就无法获取到相应的属性,从而起到属性私有化的作用。

    对于私有方法,可使用相同方式实现。