es6 类的私有属性_ES6中class私有属性和私有方法

ES6新增的class语法非常帅,但是围绕这个新的语法糖,在class中如何实现静态属性、私有属性、私有方法的问题,成为了大家探讨的话题。本文打算绕过现有的weakmap、symbol的方案,从最简单的实践中抽取出满足要求的方案。

静态属性

静态方法非常好实现,就是在普通方法名前面添加static关键字。那么静态属性呢?其实也可以通过static关键字来处理:

class MyClass {

static get name() {

return 'my name'

}

}

这样就可以使用MyClass.name获取静态属性值了。而且因为没有设置setter,所以这个静态属性值还不能被改变。当然,你也可以把setter加上去。

私有属性

首先要搞明白“私有属性”意味着几层意思,不是说形式上满足需求就可以,而是要从代码的机理上实现“私有”效果:

1 class内部不同方法间可以使用,因此this要指向实例化对象(必须)

2 不能被外部访问,因此实例化对象person.name既不能获得值,也不能设定值,应该返回undefined,甚至应该在实例化之后,并不知道有name这个属性存在,开发者甚至可以自己再person.name = 'new name'动态去创建一个非私有属性(必须)

3 不能被继承,因此extends后子类不具备该属性(必须)

4 方便的调用方式,比如类this._name形式(备选)

上面这些应该是作为私有属性的主要条件,如果连这些都不满足,很难谈得上叫“私有属性”。

实现方法:

var attributions = {}

function get(that, key) {

return attributions[that] && attributions[that][key]

}

function set(that, key, value) {

if(!attributions[that]) attributions[that] = {}

attributions[that][key] = value

}

class MyClass {

set() {

set(this, 'name', 'my name')

}

get() {

let name = get(this, 'name')

console.log(name)

}

}

在类外面有一个辅助对象attributions,两个辅助函数set, get。它们将不被实例化对象直接访问,因此是一个相对封闭的空间,外部完全无法访问set, get函数操作的内容,但对于类的实例化对象而已,确实有自己对应的属性内容,因此,这种方案,可以代替类内部的私有属性的功能。

私有方法

理论上讲,私有属性和私有方法的区别是,私有方法是函数。因此,实际上,上面私有属性的实现过程中已经实现了私有方法,就是上面的set, get两个辅助函数,这两个函数帮助类完成一些操作,同时对于每一个实例化对象而言都可以设置对应的值,而且也不会被外部获取。

getter和setter的实现

现在很多类实现了getter和setter,将内部的数据管理和自身的属性分开,改变数据和改变属性是两回事。

var events = {}

var data = {}

class MyClass {

on(event, handler) {

if(!events[event]) events[event] = []

events[event].push(handler)

}

trigger(event, params = []) {

let evts = events[event]

if(Array.isArray(evts)) evts.forEach(callback => {

if(typeof callback === 'function') {

if(Array.isArray(params)) callback.apply(this, params)

else callback.call(this, params)

}

})

}

get(key) {

return data[this] && data[this][key]

}

set(key, value, notify = true) {

if(!data[this]) data[this] = {}

data[this][key] = value

if(notify) {

this.trigger('change:' + key, value)

}

}

call(factory, ...args) {

factory.apply(this, args)

}

}

上面的类中定义了我们最常用的on, trigger, get, set, call这几个方法。使用方法:

var a = new MyClass()

a.on('change:name', value => console.log(value))

a.set('name', 'my value')

这样不仅可以有效的管理组织自己的数据,而且还可以通过绑定,实现数据变化的监听。

求个兼职,如果您有web开发方面的需要,可以联系我,生活不容易,且行且珍惜。

我的个人博客 www.tangshuang.net 这里就不留信息了,请在博客留言,我会联系你

你可能感兴趣的:(es6,类的私有属性)