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

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

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

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

当前回答

就我个人而言,我喜欢绑定操作符::的建议,然后将其与@d13提到的解决方案结合起来,但现在坚持使用@d13的答案,在这里您为类使用export关键字,并将私有函数放在模块中。

还有一个棘手的解决方案,这里没有提到,下面是更实用的方法,将允许它在类中拥有所有的私有道具/方法。

Private.js

export const get = state => key => state[key];
export const set = state => (key,value) => { state[key] = value; }

. js

import { get, set } from './utils/Private'
export default class Test {
  constructor(initialState = {}) {
    const _set = this.set = set(initialState);
    const _get = this.get = get(initialState);

    this.set('privateMethod', () => _get('propValue'));
  }

  showProp() {
    return this.get('privateMethod')();
  }
}

let one = new Test({ propValue: 5});
let two = new Test({ propValue: 8});
two.showProp(); // 8
one.showProp(); // 5

请对此提出意见。

其他回答

根据ES2022,我们可以在JavaScript类中添加私有属性和方法。

我们可以通过在私有字段的名称前预先挂起#来定义它们。

演示:

类Something { #property = "test";//通过在属性名后面加上#,我们使它成为私有的。 } var instance = new Something(); console.log(实例。#产权);私有字段'#property'必须在一个外围类中声明

另一种方式类似于上两个帖子

class Example {
  constructor(foo) {

    // privates
    const self = this;
    this.foo = foo;

    // public interface
    return self.public;
  }

  public = {
    // empty data
    nodata: { data: [] },
    // noop
    noop: () => {},
  }

  // everything else private
  bar = 10
}

const test = new Example('FOO');
console.log(test.foo); // undefined
console.log(test.noop); // { data: [] }
console.log(test.bar); // undefined

答案是“不”。但是你可以像这样创建对属性的私有访问:

使用模块。模块中的所有内容都是私有的,除非使用export关键字将其设为公有。 在模块内部,使用函数闭包:http://www.kirupa.com/html5/closures_in_javascript.htm

(可以使用符号来确保隐私的建议在ES6规范的早期版本中是正确的,但现在不再是这样:https://mail.mozilla.org/pipermail/es-discuss/2014-January/035604.html和https://stackoverflow.com/a/22280202/1282216。有关符号和隐私的详细讨论,请参阅:https://curiosity-driven.org/private-properties-in-javascript)

我找到了一个非常简单的解决方案,只需使用Object.freeze()。当然,问题是以后你不能向对象添加任何东西。

class Cat {
    constructor(name ,age) {
        this.name = name
        this.age = age
        Object.freeze(this)
    }
}

let cat = new Cat('Garfield', 5)
cat.age = 6 // doesn't work, even throws an error in strict mode

我用这个模式,它总是对我有效

class Test { constructor(data) { class Public { constructor(prv) { // public function (must be in constructor on order to access "prv" variable) connectToDb(ip) { prv._db(ip, prv._err); } } // public function w/o access to "prv" variable log() { console.log("I'm logging"); } } // private variables this._data = data; this._err = function(ip) { console.log("could not connect to "+ip); } } // private function _db(ip, err) { if(!!ip) { console.log("connected to "+ip+", sending data '"+this.data+"'"); return true; } else err(ip); } } var test = new Test(10), ip = "185.167.210.49"; test.connectToDb(ip); // true test.log(); // I'm logging test._err(ip); // undefined test._db(ip, function() { console.log("You have got hacked!"); }); // undefined