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

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值