是否可以在ES6类中创建私有属性?

举个例子。 如何阻止访问instance.property?

class Something {
  constructor(){
    this.property = "test";
  }
}

var instance = new Something();
console.log(instance.property); //=> "test"

当前回答

使用WeakMap可以在类中拥有私有方法。

根据MDN网络文档:

WeakMap对象是键/值对的集合,其中键仅为对象,值可以是任意值。 键中的对象引用是弱保存的,这意味着如果不再有对该对象的其他引用,则它们是垃圾收集(GC)的目标。

这是一个创建带有私有成员_items的Queue数据结构的例子,该成员_items包含一个数组。

const _items = new WeakMap();

class Queue {    
    constructor() {
        _items.set(this, []);
    }

    enqueue( item) {
        _items.get(this).push(item);
    }    

    get count() {
        return _items.get(this).length;        
    }

    peek() {
        const anArray = _items.get(this);
        if( anArray.length == 0)
            throw new Error('There are no items in array!');

        if( anArray.length > 0)
            return anArray[0];
    }

    dequeue() {        
        const anArray = _items.get(this);
        if( anArray.length == 0)
            throw new Error('There are no items in array!');

        if( anArray.length > 0)
            return anArray.splice(0, 1)[0];
    }    
}

使用的例子:

const c = new Queue();
c.enqueue("one");
c.enqueue("two");
c.enqueue("three");
c.enqueue("four");
c.enqueue("five");
console.log(c);

私有成员_items是隐藏的,不能在Queue对象的属性或方法中看到:

然而,Queue对象中的私有成员_items可以通过以下方式访问:

const anArray = _items.get(this);

其他回答

使用WeakMap可以在类中拥有私有方法。

根据MDN网络文档:

WeakMap对象是键/值对的集合,其中键仅为对象,值可以是任意值。 键中的对象引用是弱保存的,这意味着如果不再有对该对象的其他引用,则它们是垃圾收集(GC)的目标。

这是一个创建带有私有成员_items的Queue数据结构的例子,该成员_items包含一个数组。

const _items = new WeakMap();

class Queue {    
    constructor() {
        _items.set(this, []);
    }

    enqueue( item) {
        _items.get(this).push(item);
    }    

    get count() {
        return _items.get(this).length;        
    }

    peek() {
        const anArray = _items.get(this);
        if( anArray.length == 0)
            throw new Error('There are no items in array!');

        if( anArray.length > 0)
            return anArray[0];
    }

    dequeue() {        
        const anArray = _items.get(this);
        if( anArray.length == 0)
            throw new Error('There are no items in array!');

        if( anArray.length > 0)
            return anArray.splice(0, 1)[0];
    }    
}

使用的例子:

const c = new Queue();
c.enqueue("one");
c.enqueue("two");
c.enqueue("three");
c.enqueue("four");
c.enqueue("five");
console.log(c);

私有成员_items是隐藏的,不能在Queue对象的属性或方法中看到:

然而,Queue对象中的私有成员_items可以通过以下方式访问:

const anArray = _items.get(this);

我相信在构造函数中使用闭包是可能获得“两全其美”的。有两种变化:

所有数据成员都是私有的

函数myFunc() { console.log(' x的值:' + this.x); this.myPrivateFunc (); } 函数myPrivateFunc() { console.log(' x的增强值:' +(此。X + 1)); } 类测试{ 构造函数(){ Let internal = { X: 2, }; 内部的。myPrivateFunc = myPrivateFunc.bind(内部); 这一点。myFunc = myFunc.bind(内部); } };

有些成员是私有的

注意:这确实很难看。如果您知道更好的解决方案,请编辑此回复。

function myFunc(priv, pub) { pub.y = 3; // The Test object now gets a member 'y' with value 3. console.log('Value of x: ' + priv.x); this.myPrivateFunc(); } function myPrivateFunc() { pub.z = 5; // The Test object now gets a member 'z' with value 3. console.log('Enhanced value of x: ' + (priv.x + 1)); } class Test { constructor() { let self = this; let internal = { x : 2, }; internal.myPrivateFunc = myPrivateFunc.bind(null, internal, self); this.myFunc = myFunc.bind(null, internal, self); } };

是的-你可以创建封装的属性,但它没有与访问修饰符(公共|私有)至少不是与ES6。

下面是一个简单的例子,如何用ES6完成:

用类词创建类

2在构造函数内部使用let OR const保留字声明块作用域变量->因为它们是块作用域,所以不能从外部访问(封装)

为了允许对这些变量进行一些访问控制(setter |getter),你可以在它的构造函数中使用:this.methodName=function(){}语法声明实例方法

"use strict";
    class Something{
        constructor(){
            //private property
            let property="test";
            //private final (immutable) property
            const property2="test2";
            //public getter
            this.getProperty2=function(){
                return property2;
            }
            //public getter
            this.getProperty=function(){
                return property;
            }
            //public setter
            this.setProperty=function(prop){
                property=prop;
            }
        }
    }

现在让我们检查一下:

var s=new Something();
    console.log(typeof s.property);//undefined 
    s.setProperty("another");//set to encapsulated `property`
    console.log(s.getProperty());//get encapsulated `property` value
    console.log(s.getProperty2());//get encapsulated immutable `property2` value

我现在听到的建议是使用WeakMaps来保存私人数据,以供其他看客参考。

下面是一个更清晰、有效的例子:

function storePrivateProperties(a, b, c, d) {
  let privateData = new WeakMap;
  // unique object as key, weak map can only accept object as key, when key is no longer referened, garbage collector claims the key-value 
  let keyA = {}, keyB = {}, keyC = {}, keyD = {};

  privateData.set(keyA, a);
  privateData.set(keyB, b);
  privateData.set(keyC, c);
  privateData.set(keyD, d);

  return {
    logPrivateKey(key) {
      switch(key) {
      case "a":
        console.log(privateData.get(keyA));
        break;
      case "b":
        console.log(privateData.get(keyB));
        break;
      case "c":
        console.log(privateData.get(keyC));
        break;
      case "d":
        console.log(privateData.set(keyD));
        break;
      default:
        console.log(`There is no value for ${key}`)
      }
    }
  }
}

我已经开发了一个模块,帮助您使用的访问限制 JavaScript类,叫做Capsulable。(私有和受保护的静态)

如果您感兴趣,请查看下面的软件包。 https://github.com/hmmhmmhm/capsulable

const Capsulable = require('capsulable')
const Field = Capsulable()

class A {
    constructor(_field){
        // Configure data fields.
        Field(this, _field)

        // The code below provides access to
        // the data fields when creating
        // functions within the class.
        Field(this).private
        Field(this).protected
        Field(this).protectedStatic
    }
}

module.exports = A