詳解如何在JavaScript中使用裝飾器
Decorator裝飾器是ES7的時候提案的特性,目前處于Stage 3候選階段(2022年10月)。
裝飾器簡單來說就是修改類和類方法的語法糖,很多面向對象語言都有裝飾器這一特性。
為了使用裝飾器特性,我們需要用進行babel轉義。這里需要用到的是@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 }], // ... ], // ... }, } // ... } ] }
使用
先來一圖了解裝飾器語法。
語法: @+函數名
@frozen class Foo { @throttle(500) expensiveMethod() {} }
類裝飾器
參數target是類本身
function testable(target) { target.isTestable = true; } @testable class MyTestableClass { // ... } MyTestableClass.isTestable // true
帶參數的修飾器
@+返回裝飾器函數的表達式
function testable(isTestable) { return function(target) { target.isTestable = isTestable; } } @testable(true) class MyTestableClass {} MyTestableClass.isTestable // true @testable(false) class MyClass {} MyClass.isTestable // false
類成員裝飾器
參數:
- target:被修飾的類的原型對象
- name:類成員的名字
- descriptor:類成員的描述對象
function readonly(target, name, descriptor){ // descriptor對象原來的值如下 // { // value: specifiedFunction, // enumerable: false, // configurable: true, // writable: true // }; descriptor.writable = false; return descriptor; } class Person { @readonly name() { return `${this.first} ${this.last}` } }
多個裝飾器的執(zhí)行順序
洋蔥模型,先從外到內進入,然后由內向外執(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
應用
延遲
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é)流
如果在定時器的時間范圍內再次觸發(fā),則不予理睬,等當前定時器完成,才能啟動下一個定時器任務。
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ā)則刪除原來的定時器,建立新的定時器。
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; } }
到此這篇關于詳解如何在JavaScript中使用裝飾器的文章就介紹到這了,更多相關JavaScript使用裝飾器內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
JavaScript中正則表達式使數字、中文或指定字符高亮顯示
這篇文章主要介紹了JavaScript中正則表達式使數字、中文或指定字符高亮顯示,需要的朋友可以參考下2017-10-10