资讯专栏INFORMATION COLUMN

ES6中class私有属性和私有方法

bergwhite / 3486人阅读

摘要:新增的语法非常帅,但是围绕这个新的语法糖,在中如何实现静态属性私有属性私有方法的问题,成为了大家探讨的话题。私有方法理论上讲,私有属性和私有方法的区别是,私有方法是函数。

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 类入门

    摘要:静态属性静态方法目前支持静态方法表示,类属性及静态属性目前作为提案还未正式成为标准。在中,抽象类不能用来实例化对象,主要做为其它派生类的基类使用。不同于接口,抽象类可以包含成员的实现细节。中也是这样规定的抽象类不允许直接被实例化。 尝试重写 在此之前,通过《JavaScript => TypeScript 入门》已经掌握了类型声明的写法。原以为凭着那一条无往不利的规则,就可以开开心心的...

    geekidentity 评论0 收藏0
  • ES6 系列之私有变量的实现

    摘要:前言在阅读入门的时候,零散的看到有私有变量的实现,所以在此总结一篇。构造函数应该只做对象初始化的事情,现在为了实现私有变量,必须包含部分方法的实现,代码组织上略不清晰。 前言 在阅读 《ECMAScript 6 入门》的时候,零散的看到有私有变量的实现,所以在此总结一篇。 1. 约定 实现 class Example { constructor() { this...

    lentoo 评论0 收藏0
  • 面向对象特征之封装-Es6Class私有受保护的属性方法

    摘要:熟悉面向对象编程的都知道,面向对象编程最重要的原则之一从外部接口划分内部接口。所以,面向对象编程就类似于汽车一样。 熟悉面向对象编程的都知道,面向对象编程最重要的原则之一 - 从外部接口划分内部接口。也就是说,针对某一类事物,我们其实并不是那么在乎其内部究竟是怎样去实现的,只关心怎样使用而已。 为了理解这点,让我们先来看看现实生活中的列子。通常,我们使用的设备非常复杂。但是从外部接口界...

    neuSnail 评论0 收藏0
  • ES5 模拟 ES6 的 Symbol 实现私有成员

    摘要:中有类语法,定义类变得简单了然而,并没有提供私有属性。按照此思路,在中其实也很容易模拟私有成员。问题在于模拟的唯一性。在开发阶段这个值仍然是不可预料的。综上,中模拟来实现私有属性的目的已经达到了。 ES6 中有类语法,定义类变得简单了 class Person { constructor(name) { this._name = name; } ...

    livem 评论0 收藏0
  • ES6的一个基础类,支持私有属性方法,支持eventmix

    摘要:绑定事件,传入一个回调函数,但是这里还给加了一个功能,就是第三个参数规定回调函数执行的顺序。比如当你给同一个事件传入了多个回调函数,怎么来规定它们之间的顺序呢通过传入第三个参数即可,数字越小的,越靠前执行。 ES6提供了完整的class语法,因此,可以非常方便的使用extends关键字对类进行扩展(继承)。为了实现类的一些基础功能,我撰写了下面这个类,用以被其他类继承,拥有这个基础类的...

    Jeffrrey 评论0 收藏0

发表评论

0条评论

bergwhite

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<