詳解如何在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)文章
javascript 圖片上傳預(yù)覽-兼容標(biāo)準(zhǔn)
js圖片上傳預(yù)覽2009-06-06JavaScript中正則表達(dá)式使數(shù)字、中文或指定字符高亮顯示
這篇文章主要介紹了JavaScript中正則表達(dá)式使數(shù)字、中文或指定字符高亮顯示,需要的朋友可以參考下2017-10-10JavaScript利用Date實(shí)現(xiàn)簡(jiǎn)單的倒計(jì)時(shí)實(shí)例
在日常開(kāi)發(fā)的時(shí)候經(jīng)常遇到關(guān)于倒計(jì)時(shí)的需求,下面這篇文章就給主要介紹了JavaScript利用Date實(shí)現(xiàn)倒計(jì)時(shí)效果的方法示例,文中主要實(shí)現(xiàn)了倒計(jì)時(shí)和倒計(jì)時(shí)結(jié)束搶購(gòu)的按鈕才可以被點(diǎn)擊的效果,有需要的朋友可以參考借鑒。2017-01-01微信小程序?qū)崿F(xiàn)購(gòu)物車代碼實(shí)例詳解
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)購(gòu)物車代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08微信小程序開(kāi)發(fā)之自定義tabBar的實(shí)現(xiàn)
這篇文章主要介紹了微信小程序開(kāi)發(fā)之自定義tabBar的實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09javascript實(shí)現(xiàn)簡(jiǎn)單的二級(jí)聯(lián)動(dòng)
這篇文章主要介紹了javascript實(shí)現(xiàn)簡(jiǎn)單的二級(jí)聯(lián)動(dòng),非常的實(shí)用,需要的朋友可以參考下2015-03-03原生js實(shí)現(xiàn)trigger方法示例代碼
這篇文章主要給大家介紹了關(guān)于利用原生js實(shí)現(xiàn)trigger方法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用js具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05