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 这里就不留信息了,请在博客留言,我会联系你