详解ES6实现类的私有变量的几种写法

2023-12-09前端开发
66

当我们在使用面向对象程序设计时,往往需要实现类的私有变量,以限制对变量的直接访问,防止出现意外修改。ES6中,有多种方式可以实现类的私有变量。

一种常见的方式是使用Symbol实现,具体实现方法如下:

  1. 首先定义一个Symbol类型的变量,在模块或类的顶层定义,确保其唯一性,比如:
const _privateVariable = Symbol('privateVariable');
  1. 在类的构造函数中将私有变量绑定到this上,从而使得该变量变成了该类实例的属性。
class Example {
  constructor(value) {
    this[_privateVariable] = value;
  }
}
  1. 接着可以在该类的方法中使用私有变量,如:
class Example {
  constructor(value) {
    this[_privateVariable] = value;
  }
  getValue() {
    return this[_privateVariable];
  }
}

这种方法使用了Symbol的唯一性,确保每个类实例都有自己的私有变量,并且不会被外部代码篡改。

另一种方法是使用WeakMap实现,它的原理是将私有变量作为WeakMap的键,确保仅在该类实例被垃圾回收时才会被清除。具体实现方法如下:

  1. 定义一个空的WeakMap对象:
const _privateVariables = new WeakMap();
  1. 在类的构造函数中将私有变量添加到WeakMap对象中,从而使得该变量变成了该类实例的私有变量。
class Example {
  constructor(value) {
    _privateVariables.set(this, value);
  }
}
  1. 在该类的方法中可以通过WeakMap对象获取私有变量,如:
class Example {
  constructor(value) {
    _privateVariables.set(this, value);
  }
  getValue() {
    return _privateVariables.get(this);
  }
}

这种方法保护了私有变量,并且在垃圾回收时自动清除私有变量。

示例1:

const _privateVariable = Symbol('privateVariable');

class Example {
  constructor(value) {
    this[_privateVariable] = value;
  }
  getValue() {
    return this[_privateVariable];
  }
}

let example1 = new Example('private1');
console.log(example1.getValue()); // 返回'private1'
example1[_privateVariable] = 'public1';
console.log(example1.getValue()); // 返回'private1',因为私有变量并没有被更改

在示例1中,我们使用了Symbol来实现私有变量,确保了其唯一性。在类实例化时,私有变量被绑定到对应实例中,保证了私有变量的访问性和独立性。当我们尝试篡改私有变量时,由于其唯一性无法被更改,因此即便尝试也无法访问到被保护的值。

示例2:

const _privateVariables = new WeakMap();

class Example {
  constructor(value) {
    _privateVariables.set(this, value);
  }
  getValue() {
    return _privateVariables.get(this);
  }
}

let example1 = new Example('private1');
console.log(example1.getValue()); // 返回'private1'
example1.value = 'public1';
console.log(example1.getValue()); // 返回'private1',因为私有变量并没有被更改

在示例2中,我们使用了WeakMap来实现私有变量,确保了私有变量的安全性和私密性。在类实例化时,私有变量被加到WeakMap中,并且同样保证了私有变量的独立性和访问性。与示例1不同的是,在尝试篡改私有变量时,我们注入的public1无法更改WeakMap中私有变量的键名和值,因此例子中为'private1'的值得到保障并被返回。

The End

相关推荐

layui实现图片上传成功后回显点击放大图片功能
layui实现图片上传成功后回显点击放大图片功能,html代码部分: !-- html代码--div class="layui-form-item" label class="layui-form-label"上传图片/label div class="layui-input-block" button type="button" class="layui-btn" id="license-auth-letter-...
2025-09-06 前端开发
202

Layui实现数据表格中鼠标悬停图片放大离开时恢复原图
Layui实现数据表格中鼠标悬停图片放大离开时恢复原图的效果,最终效果如下图所示: 实现代码如下,在done函数中调用hoverOpenImg方法 var tableIns = window.demoTable = table .render({ elem : '#idTest', id : 'idTest', url : '/postData', //width : 150...
2025-09-04 前端开发
112

layui点击文本输入框调起弹出选择框并选择内容的两种方法参考
我们在用到layui时候,需要点击文本输入框调起弹出选择框并选择内容,这个要怎么操作呢?以下两种方法可以参考: 1、点击名称,弹出信息弹框,选择表格中的某一行,实现效果如下: html页面代码 !--计量器具弹出层-- div id="equipment" lay-filter="equipmen...
2025-09-02 前端开发
167

网站部署https后百度地图不显示问题
https的网站如果引用百度地图,会出现加载不了的问题,这是因为涉及到跨域问题,网站是https的,但是引用百度地图的是http的,这个要怎么操作呢? 比如我引用的地址:http://api.map.baidu.com/api?v=2.0ak=AK显示 后来看了一下,少了一个s=1字段,加一下s=1...
2025-07-28 前端开发
139

微信小程序实现点击复制功能和手机拨打电话功能
做小程序项目的时候,客户提了一个功能需求优化,就是长按文字需要复制全部内容,因为有的手机支持全选复制,有的手机不支持全选复制。 通过设置系统剪贴板的内容和获取系统剪贴板的内容实现复制功能 html相关代码: van-field value="{{form.contactPhone}}"...
2025-07-02 前端开发
78

js拖拽排序插件Sortable.js如何使用
由于项目功能需要,要实现对table中的行实现拖拽排序功能,找来找去发现Sortable.js能很好的满足这个需求,而且它还是开源的,于是乎就开始学习使用Sortable.js 特点 轻量级但功能强大 移动列表项时有动画 支持触屏设备和大多数浏览器(IE9及以下除外) 支持...
2025-06-12 前端开发
161