摘要:新增的语法非常帅,但是围绕这个新的语法糖,在中如何实现静态属性私有属性私有方法的问题,成为了大家探讨的话题。私有方法理论上讲,私有属性和私有方法的区别是,私有方法是函数。
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 这里就不留信息了,请在博客留言,我会联系你
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/86801.html
摘要:静态属性静态方法目前支持静态方法表示,类属性及静态属性目前作为提案还未正式成为标准。在中,抽象类不能用来实例化对象,主要做为其它派生类的基类使用。不同于接口,抽象类可以包含成员的实现细节。中也是这样规定的抽象类不允许直接被实例化。 尝试重写 在此之前,通过《JavaScript => TypeScript 入门》已经掌握了类型声明的写法。原以为凭着那一条无往不利的规则,就可以开开心心的...
摘要:前言在阅读入门的时候,零散的看到有私有变量的实现,所以在此总结一篇。构造函数应该只做对象初始化的事情,现在为了实现私有变量,必须包含部分方法的实现,代码组织上略不清晰。 前言 在阅读 《ECMAScript 6 入门》的时候,零散的看到有私有变量的实现,所以在此总结一篇。 1. 约定 实现 class Example { constructor() { this...
摘要:熟悉面向对象编程的都知道,面向对象编程最重要的原则之一从外部接口划分内部接口。所以,面向对象编程就类似于汽车一样。 熟悉面向对象编程的都知道,面向对象编程最重要的原则之一 - 从外部接口划分内部接口。也就是说,针对某一类事物,我们其实并不是那么在乎其内部究竟是怎样去实现的,只关心怎样使用而已。 为了理解这点,让我们先来看看现实生活中的列子。通常,我们使用的设备非常复杂。但是从外部接口界...
摘要:中有类语法,定义类变得简单了然而,并没有提供私有属性。按照此思路,在中其实也很容易模拟私有成员。问题在于模拟的唯一性。在开发阶段这个值仍然是不可预料的。综上,中模拟来实现私有属性的目的已经达到了。 ES6 中有类语法,定义类变得简单了 class Person { constructor(name) { this._name = name; } ...
摘要:绑定事件,传入一个回调函数,但是这里还给加了一个功能,就是第三个参数规定回调函数执行的顺序。比如当你给同一个事件传入了多个回调函数,怎么来规定它们之间的顺序呢通过传入第三个参数即可,数字越小的,越靠前执行。 ES6提供了完整的class语法,因此,可以非常方便的使用extends关键字对类进行扩展(继承)。为了实现类的一些基础功能,我撰写了下面这个类,用以被其他类继承,拥有这个基础类的...
阅读 3541·2023-04-26 02:10
阅读 1237·2021-11-22 15:25
阅读 1640·2021-09-22 10:02
阅读 875·2021-09-06 15:02
阅读 3427·2019-08-30 15:55
阅读 576·2019-08-30 13:58
阅读 2732·2019-08-30 12:53
阅读 3019·2019-08-29 12:38