当前位置 : 主页 > 网络编程 > JavaScript >

JavaScript getter setter金字塔​​​​​​​

来源:互联网 收集:自由互联 发布时间:2023-01-19
目录 引言 函数 getters setters getter-getters setter-setter iterables promises Observables GetterSetterFunctionValue async iterables operators 引言 英文链接:staltz.com/javascript- 函数是JavaScript的基石。 它是一种灵活
目录
  • 引言
  • 函数
  • getters
  • setters
  • getter-getters
  • setter-setter
  • iterables
  • promises
  • Observables
    • GetterSetterFunctionValue
  • async iterables
    • operators

      引言

      英文链接: staltz.com/javascript-…

      函数是JavaScript的基石。 它是一种灵活的、抽象的,可作为其他抽象的基础, 如:Promise、Iterables、Observables等。 之前我在会议或研讨会中传递这些概念,随着时间的推移,我发现这些抽象的概念可以抽象为金字塔状排列的模型,在本文中,将介绍金字搭中的各层。

      函数

      JavaScript的基础是一级值,如: numbers、strings、objects、booleans等。 虽然,您可以只使用这些值和控制流(if/else/for等)来编写程序,但很快您可能需要编写一个新的函数来改进您的程序。

      JavaScript中必须通过函数进行抽象,像异步I/O操作等通常都必须使用callback回调函数。 JavaScript中的函数,与【函数式编程】中的纯函数不同,建议最好将它们简单理解为“流程”,因为它只得惰性的可重用代码块,具有可选的输入(参数)和可选的输出(返回值)

      与硬编码相比,函数有以下几个重要的好处:

      • 懒惰/可重用性, 函数内的代码必须是惰性的(即除非被调用,否则不会执行)才能使其可重用
      • 实现的灵活性,函数的使用者并不关心函数内部是如何实现的,这意味着可以各种方式灵活的实现函数。

      getters

      getter是一种不用传递任何参数但需要有返回值的函数。
      函数定义: () => X

      getter是一种不用传递任何参数但需要有返回值的函数。 JavaScript中有许多这样的getter, 例如: Math.random()、Date.now()等

      getter作为值的抽象也很有用,例如:user 与 getUser

      const user = {name: 'Alice', age:30};
      console.log(user.name); // Alice
      function getUser(){
      	return {name: 'Alice', age:30};
      }
      console.log(getUser().name); // Alice

      通过使用getter, 我们可以利用函数的一个好处: 惰性. 即我们不调用 getUser()user对象就不会被白白创建。 同时,我们利用了函数的另一好处:实现的灵活性, 因为我们可以通过多种不同的方式来返回对象。

      getter还允许我们对副作用有一个钩子,当执行getter时,我们可以触发有用的副作用函数,比如console.log输出日志 或是 触发Analytics事件等,例如:

      function getUser(){
      	Analytics.sendEvent('User object is now being accessed');
      	return {name:'Alice', age:30};
      }

      getter上的计算,也是可以抽象的。例如:

      function add(getX, getY){
      	return function getZ(){
      		const x = getX();
      		const y = getY();
      		return x + y;
      	}
      }

      当getter返回不可预测的值时,这种抽象计算的好处更加明显,例如:使用getter添加Math.random:

      const getTen = () => 10;
      const getTenPlusRandom = add(getTen, Math.random);
      
      console.log(getTenPlusRandom()); // 10.948117215055046
      console.log(getTenPlusRandom()); // 10.796721274448556
      console.log(getTenPlusRandom()); // 10.15350303918338
      console.log(getTenPlusRandom()); // 10.829703269933633

      比较常见的是getter与Promise一起搭配使用,因为Promise是不可重用的计算,因此,将Promise的构造函数包装在一个getter中(如我们熟知的"工厂函数"或"thunk")使其可重用。

      setters

      setters是有一个或多个输入参数,但没有返回值的函数。
      函数定义: X => ()

      setters是有一个或多个输入参数,但没有返回值的函数。 在JavaScript运行时或DOM中有许多这样的setters, 比如: console.log(x), document.write(x)等。

      与getter不同,setter通常不用抽象。 因为函数没有返回值,这意味着函数仅用于发送数据或执行JavaScript命令等。 例如, 上文中的getter getTen是数字10的抽象,我们可以将它作为值进行传递,但如果将函数setTen作为值传递是没有意义的,因为它没有返回值。

      换句话说,setter可以是其他setter的简单包装器。例如:简单包装下setter console.log:

      function fancyConsoleLog(str) {
        console.log('⭐ ' + str + ' ⭐');
      }

      getter-getters

      getter-getters是一种不需要输入参数且返回一个getter的函数。
      函数定义: () => (() => X)

      “getter-getter”: 一种特殊类型的getter,其返回值是一个getter.

      对getter的原始需求是使用getter的返回值进行迭代。
      例如,我们想显示二次幂的数字序列,我们可以使用getter getNextPowerOfTwo()

      let i = 2;
      function getNextPowerOfTwo() {
        const next = i;
        i = i * 2;
        return next;
      }
      console.log(getNextPowerOfTwo()); // 2
      console.log(getNextPowerOfTwo()); // 4
      console.log(getNextPowerOfTwo()); // 8
      console.log(getNextPowerOfTwo()); // 16
      console.log(getNextPowerOfTwo()); // 32
      console.log(getNextPowerOfTwo()); // 64
      console.log(getNextPowerOfTwo()); // 128

      在上面示例代码中,变量i是全局声明的,若我们想重新迭代序列,则必须要重置变量i, 从而泄漏了getter的实现细节。

      若想将上述代码变为可重用且不包含全局变量,我们需要将getter封装在另一个函数中,这个包装函数也是一个getter.

      function getGetNext() {
        let i = 2;
        return function getNext() {
          const next = i;
          i = i * 2;
          return next;
        }
      }
      
      let getNext = getGetNext();
      console.log(getNext()); // 2
      console.log(getNext()); // 4
      console.log(getNext()); // 8
      getNext = getGetNext(); //  
      上一篇:JavaScript本地存储与会话存储的实现介绍
      下一篇:没有了
      网友评论