从零开始学_JavaScript_系列(62)——class(3)setter和getter、Generator、async函数

来源:互联网 发布:linux解压tar包 编辑:程序博客网 时间:2024/06/06 20:33

6、setter和getter

之前说过,常规情况下,类是没办法直接实现变量的。

有一种变相的做法,是用es5的setter和getter特性来实现。

但这种办法并不是完美的,有两个缺陷:

  1. setter和getter,就功能来说更强大,但对于一般需求来说,又过于复杂了;
  2. setter和getter本身只是起到一个代理的作用,本身并不能真正存储变量,还是需要通过一个间接的变量来存储他;
  3. 这个用于存储的间接的变量,是可以被直接访问到的。

但setter和getter也有优点:

引自《 API design for C++ 》

  1. 有效性验证(可以在setter里检查设置的值是否在许可区间里)
  2. 惰性求值(比如一个成员计算过于耗时,而这个类的用户(这里的用户指其他程序员)不一定需要时,可以在getter方法调用的时候再计算)
  3. 缓存额外的操作(比如用户调用setter方法时,可以把这个值更新到配置文件里)
  4. 通知(其它模块可能需要在某个值发生变化的时候做一些操作,那么就可以在setter里实现)
  5. 调试(可以方便的打印设置日志,从而追踪错误)
  6. 同步(如果多线程访问需要加锁的话,setter里加锁不是很容易么)
  7. 更精细的权限访问(比如private变量只有getter没有setter,那客户对该变量就是只读了,而类的内部代码可以读写)
  8. 维护不变式关系(比如一个类内部要维持连个变量a和b有a = b * 2的关系,那么在a和b的setter里计算就能维持这样的关系)

以上引用内容复制自:

作者:浅墨链接:https://www.zhihu.com/question/21401198/answer/37192335来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

对于js来说,有用的有:

  1. 常见情况下:1(超限则赋值无效)、5(很好用的说)、8(比如改了当前值后,顺便改了和他联动的另外一个值)
  2. 不常见情况有:2(类似的效果可以参考Vue的计算属性、4(比如关键属性被修改,log一发)、7(比如只允许读或只允许写)

关于class应用本特性的例子可以参考我的这篇博客:利用setter和getter实现数据校验

7、Generator函数

不懂Generator函数的,请从我的这篇博客开始阅读Generator函数(1)基本概念和示例。

没有基础的话,直接阅读本篇内容是很有可能看不懂的。

Generator函数在class里面的时候,在函数名之前加星号即可:

class Foo {    *g() {        yield "1";        yield "2"        return "3"    }}let p = new Foo()let i = p.g()i.next();   // {value: "1", done: false}i.next();   // {value: "1", done: false}i.next();   // {value: "3", done: true}

利用Generator函数,利用扩展运算符自动调用遍历器接口:

class Foo {    *[Symbol.iterator]() {        yield "1"        yield "2"    }}let p = new Foo()console.log([...p]) // ["1", "2"]

8、async函数

既然支持Generator函数,当然也支持async函数啦。

使用方法和Generator函数的套路是一样的,在函数名前加async就行了。

示例代码如下:

function delay(msg) {    return new Promise(resolve => {        setTimeout(function () {            resolve(msg)        }, 1000)    })}class Foo {    async foo() {        let r1 = await delay('1').then(msg => {            console.log(msg)            return msg        })        console.log(r1)        await delay('2').then(msg => {            console.log(msg)        })    }}let p = new Foo()// "1"  第一个await表达式里then的log// "1"  r1的log// "2"  第二个await表达式里then的log
阅读全文
0 0
原创粉丝点击