JS私有属性 私有方法定义(入门到精通)

私有属性作用:

  1. 在打印枚举对象时,只显示可能去调用的,隐藏掉背后辅助函数,免得杂乱
  2. 玩点花活,写一些自己才会调用,一般人不会调用的函数
  3. 不想被看到.
  4. 不想被看到. .
  5. 不想被看到. . .

下面我们直入主题,直接用5段代码,带你在实战中领会精髓:

1. Function

const createObject = () => {
  // 私有方法
  const privateMethod = () => {
    console.log('这是私有方法');
    return 'private result';
  };
  // 返回公共接口
  return {
    publicMethod() {
      const result = privateMethod();
      console.log('这是公共方法,调用了私有方法得到:', result);
    }
  };
};

const obj = createObject();
obj.publicMethod(); // 正常工作
obj.privateMethod(); // undefined - 无法访问

  • :white_check_mark:函数私有
  • :x:存在的问题是无法解耦,publicMethod没法拿出来在外部定义,否则就调用不了privateMethod

2. Symbol

const privateMethod = Symbol("private");

const createObject = () => {
  return {
    [privateMethod]: function () {
      console.log("这是私有方法");
    },
    publicMethod
  };
};
function publicMethod() {
  this[privateMethod]();
  console.log('这是公共方法');
}
const obj = createObject();
console.log(obj);
obj.publicMethod(); // 正常工作
obj[privateMethod](); // 虽然技术上可行,但需要知道 privateMethod的名称

  • :white_check_mark:可以完成解耦
  • :bulb: 虽然光看打印内容没法调用,但如果翻找源码看到定义指向的Symbol名称,比如privateMethod,就可以通过objprivateMethod调用
  • :x:依旧有显示,显示杂乱问题没法解决

3. DefineProperty

const createObject = () => {
  const a = Math.random();
  const obj = {};
  // 存储私有方法
  Object.defineProperty(obj, "privateMethod", {
    value: ()=>console.log("privateMethod"),
    // writable: true,       // 是否允许修改函数,默认false
    // enumerable: true,     // 是否允许枚举(看到)该属性,默认false
    // configurable: true,   // 是否允许删除或重新定义该属性,默认false
  });  
  // 定义公共方法
  obj.publicMethod = publicMethod;
  return obj;
};
function publicMethod() {
  this.privateMethod();
  console.log("这是公共方法");
}
const obj = createObject();
// obj.privateMethod=()=>console.log("这xxxxx法");
// delete obj.privateMethod
console.log(obj);
obj.publicMethod();
obj.privateMethod(); //虽然看不到,但若知道名称可以调用

image

  • :white_check_mark:可以完成解耦
  • :white_check_mark:可以隐藏显示,禁止修改,禁止删除
  • :bulb:可以起到幽灵函数调用的装B效果,但反之就是还可被调用

4. WeakMap

const weakmap = new WeakMap();
const createObject = () => {
  const a = Math.random();
  const obj = {};
  // 存储私有方法
  weakmap.set(obj, {
    privateMethod: () => {
      console.log("这是私有方法", a);
    },
  });
  // 定义公共方法
  obj.publicMethod = publicMethod;
  return obj;
};
function publicMethod() {
  const private1 = weakmap.get(this);
  private1.privateMethod();
  console.log("这是公共方法");
}
const obj = createObject();
console.log(obj);
obj.publicMethod();
weakmap.get(obj).privateMethod(); // 虽然技术上可行,但需要访问 weakmap
const obj1 = createObject();
console.log(obj1);
obj1.publicMethod();
weakmap.get(obj1).privateMethod();

  • :white_check_mark:可以完成解耦
  • :white_check_mark:完全隐藏显示
  • :white_check_mark:weakmap没被导出时,完全不可外部调用

PS : 如果是Class直接使用#定义私有属性,使用简单,不举例了

最后两种DefineProperty和WeakMap方法都是不错的,推荐使用

6 个赞

mark,学习!

3 个赞

感谢你的分享 。

2 个赞

class里成员前加#就是私有的了。

3 个赞

感谢分享

2 个赞

ts语法吗

2 个赞

JS TS通用

1 个赞

JS语法。私有属性 - JavaScript | MDN
其实除了类型声明和检查以外,JS已经基本覆盖了TS的大部分特性,这玩意更新很快。而且JS和TS都是参照ECMA-262规范的。

2 个赞