欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解如何在JavaScript中使用裝飾器

 更新時(shí)間:2022年10月25日 15:36:08   作者:前端lucio  
Decorator裝飾器是ES7的時(shí)候提案的特性,目前處于Stage?3候選階段(2022年10月)。裝飾器簡(jiǎn)單來(lái)說(shuō)就是修改類和類方法的語(yǔ)法糖,很多面向?qū)ο笳Z(yǔ)言都有裝飾器這一特性。本文就來(lái)說(shuō)說(shuō)如何在JavaScript中使用裝飾器,需要的可以參考一下

Decorator裝飾器是ES7的時(shí)候提案的特性,目前處于Stage 3候選階段(2022年10月)。

裝飾器簡(jiǎn)單來(lái)說(shuō)就是修改類和類方法的語(yǔ)法糖,很多面向?qū)ο笳Z(yǔ)言都有裝飾器這一特性。

為了使用裝飾器特性,我們需要用進(jìn)行babel轉(zhuǎn)義。這里需要用到的是@babel/plugin-proposal-decorators。

安裝

npm install --save-dev @babel/plugin-proposal-decorators

vite配置

import { defineConfig } from 'vite';
import babel from 'vite-plugin-babel';

export default defineConfig({
    plugins: [
        babelDev({
            babelConfig: {
                plugin: ['@babel/plugin-proposal-decorators']
            }
        }),
        // ...
    ],

    // ...
})

webpack配置

module: {
  rules: [
    {
      test: /\.(js|mjs|jsx|ts|tsx)$/,
      use: {
        loader: 'babel-loader',
        options: {
          // ... 
          plugins: [
            ['@babel/plugin-proposal-decorators', { 'legacy': true }],
            // ...
          ],
          // ...
        },
      }
      // ...
    }
  ]
}  

使用

先來(lái)一圖了解裝飾器語(yǔ)法。

語(yǔ)法: @+函數(shù)名

@frozen
class Foo {
  @throttle(500)
  expensiveMethod() {}
}

類裝飾器

參數(shù)target是類本身

function testable(target) {
  target.isTestable = true;
}

@testable
class MyTestableClass {
  // ...
}
MyTestableClass.isTestable // true

帶參數(shù)的修飾器

@+返回裝飾器函數(shù)的表達(dá)式

function testable(isTestable) {
  return function(target) {
    target.isTestable = isTestable;
  }
}
@testable(true)
class MyTestableClass {}
MyTestableClass.isTestable // true
@testable(false)
class MyClass {}
MyClass.isTestable // false

類成員裝飾器

參數(shù):

  • target:被修飾的類的原型對(duì)象
  • name:類成員的名字
  • descriptor:類成員的描述對(duì)象
function readonly(target, name, descriptor){
  // descriptor對(duì)象原來(lái)的值如下
  // {
  //   value: specifiedFunction,
  //   enumerable: false,
  //   configurable: true,
  //   writable: true
  // };
  descriptor.writable = false;
  return descriptor;
}

class Person {
  @readonly
  name() { return `${this.first} ${this.last}` }
}

多個(gè)裝飾器的執(zhí)行順序

洋蔥模型,先從外到內(nèi)進(jìn)入,然后由內(nèi)向外執(zhí)行

function dec(id){
  console.log('evaluated', id);
  return (target, property, descriptor) => console.log('executed', id);
}
class Example {
    @dec(1)
    @dec(2)
    method(){}
}
// evaluated 1
// evaluated 2
// executed 2
// executed 1

應(yīng)用

延遲

class Page {
	@delay(2000)
	onClick(a) {
    console.log("onClick");
  }
}
function delay(time) {
  return function (target, key, descriptor) {
    const oldFunction = descriptor.value;
    descriptor.value = function() {
      setTimeout(() => {
        oldFunction.apply(this, arguments);
      }, time);
    }
    return descriptor;
  }
}

節(jié)流

如果在定時(shí)器的時(shí)間范圍內(nèi)再次觸發(fā),則不予理睬,等當(dāng)前定時(shí)器完成,才能啟動(dòng)下一個(gè)定時(shí)器任務(wù)

class Page {
	@throttle(2000)
	onClick(a) {
    console.log("onClick");
  }
}
function throttle(time) {
  return function (target, key, descriptor) {
    const oldFunction = descriptor.value;
    let isLock = false;
    descriptor.value = function() {
      if(isLock) { return; }
     	isLock = true;
      oldFunction.apply(this, arguments);
      setTimeout(() => {
        isLock = false; 
      }, time);
    }
    return descriptor;
  }
}

防抖

每次事件觸發(fā)則刪除原來(lái)的定時(shí)器,建立新的定時(shí)器。

class Page {
	@debounce(2000)
	onClick(a) {
    console.log("onClick");
  }
}
function debounce(time) {
  return function (target, key, descriptor) {
    const oldFunction = descriptor.value;
    let timer = null;
    descriptor.value = function () {
      clearTimeout(timer);
      timer = setTimeout(() => {
        oldFunction.apply(this, arguments)
      }, time);
    };
    return descriptor;
  }
}

到此這篇關(guān)于詳解如何在JavaScript中使用裝飾器的文章就介紹到這了,更多相關(guān)JavaScript使用裝飾器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論