5個(gè)讓你眼前一亮的JavaScript裝飾器技巧
裝飾器
什么是裝飾器
裝飾器是一個(gè)函數(shù),它接收函數(shù)或類作為參數(shù),并返回修改后的函數(shù)或類。裝飾器可以通過 @ 符號(hào)應(yīng)用于函數(shù)或類。
下面是一個(gè)簡(jiǎn)單的裝飾器示例:
function myDecorator(target) {
// 對(duì)類或函數(shù)進(jìn)行修改
return target;
}
@myDecorator
class MyClass {
// 類的定義
}
@myDecorator
function myFunction() {
// 函數(shù)的定義
}裝飾器的作用
裝飾器可以用于許多場(chǎng)景,例如:
- 類屬性保護(hù)
- 函數(shù)參數(shù)類型檢查
- 函數(shù)返回值類型檢查
- 函數(shù)調(diào)用計(jì)時(shí)
本文將介紹裝飾器如何用于裝飾函數(shù)參數(shù)、裝飾類屬性、裝飾函數(shù)返回值和裝飾函數(shù)調(diào)用。
裝飾函數(shù)參數(shù)
參數(shù)類型檢查
裝飾器可以用于檢查函數(shù)參數(shù)的類型。下面是一個(gè)使用裝飾器對(duì)函數(shù)參數(shù)進(jìn)行類型檢查的示例:
function myParameterDecorator(target, name, descriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args) {
args.forEach((arg, index) => {
const argType = typeof arg;
if (argType !== 'number' && argType !== 'string') {
throw new Error(`Argument ${index} is of type ${argType}, but should be a string or a number`);
}
});
return originalMethod.apply(this, args);
}
return descriptor;
}
class MyClass {
@myParameterDecorator
myMethod(name, age) {
console.log(`Hello, my name is ${name} and I am ${age} years old`);
}
}
const myObject = new MyClass();
myObject.myMethod("Alice", 30); // 輸出:Hello, my name is Alice and I am 30 years old
myObject.myMethod("Bob", "thirty"); // 拋出錯(cuò)誤:Argument 1 is of type string, but should be a string or a number在上面的示例中,@myParameterDecorator 裝飾器用于在調(diào)用 myMethod 函數(shù)之前檢查傳遞給函數(shù)的每個(gè)參數(shù)是否為字符串或數(shù)字類型。如果參數(shù)不是這兩種類型之一,則拋出錯(cuò)誤。
參數(shù)默認(rèn)值
裝飾器還可以用于設(shè)置函數(shù)參數(shù)的默認(rèn)值。下面是一個(gè)使用裝飾器對(duì)函數(shù)參數(shù)設(shè)置默認(rèn)值的示例:
function myParameterDecorator(target, name, descriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(name = "World") {
return originalMethod.call(this, name);
}
return descriptor;
}
class MyClass {
@myParameterDecorator
myMethod(name) {
console.log(`Hello, ${name}`);
}
}
const myObject = new MyClass();
myObject.myMethod(); // 輸出:Hello, World
myObject.myMethod("Alice"); // 輸出:Hello, Alice在上面的示例中,@myParameterDecorator 裝飾器用于在調(diào)用 myMethod 函數(shù)時(shí)檢查參數(shù) name 是否存在。如果參數(shù) name 不存在,則使用默認(rèn)值 "World"。
裝飾類屬性
類屬性保護(hù)
裝飾器可以用于保護(hù)類屬性,防止它們被修改或直接訪問。下面是一個(gè)使用裝飾器保護(hù)類屬性的示例:
function myPropertyDecorator(target, name) {
let value = target[name];
const getter = function() {
return value;
};
const setter = function(newValue) {
if (typeof newValue === 'string') {
value = newValue;
} else {
throw new Error(`Property ${name} must be a string`);
}
};
delete target[name];
Object.defineProperty(target, name, {
get: getter,
set: setter,
enumerable: true,
configurable: true,
});
}
class MyClass {
@myPropertyDecorator
myProperty = "initial value";
}
const myObject = new MyClass();
console.log(myObject.myProperty); // 輸出:initial value
myObject.myProperty = "new value";
console.log(myObject.myProperty); // 輸出:new value
myObject.myProperty = 123;
// 拋出錯(cuò)誤:Property myProperty must be a string在上面的示例中,@myPropertyDecorator 裝飾器用于保護(hù) MyClass 類的一個(gè)屬性 myProperty。如果嘗試將屬性設(shè)置為非字符串值,則會(huì)拋出錯(cuò)誤。
類屬性初始值
裝飾器還可以用于設(shè)置類屬性的初始值。下面是一個(gè)使用裝飾器設(shè)置類屬性初始值的示例:
function myDefaultDecorator(defaultValue) {
return function(target, name) {
target[name] = defaultValue;
}
}
class MyClass {
@myDefaultDecorator('initial value')
myProperty;
}
const myObject = new MyClass();
console.log(myObject.myProperty); // 輸出:initial value在上面的示例中,@myDefaultDecorator 裝飾器用于設(shè)置 MyClass 類的一個(gè)屬性 myProperty 的初始值為 "initial value"。
裝飾函數(shù)返回值
返回類型檢查
裝飾器可以用于檢查函數(shù)返回值的類型。下面是一個(gè)使用裝飾器對(duì)函數(shù)返回值進(jìn)行類型檢查的示例:
function myReturnDecorator(target, name, descriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args) {
const result = originalMethod.apply(this, args);
if (typeof result !== 'number') {
throw new Error(`Method ${name} must return a number`);
}
return result;
}
return descriptor;
}
class MyClass {
@myReturnDecorator
myMethod() {
return 42;
}
}
const myObject = new MyClass();
console.log(myObject.myMethod()); // 輸出:42
myObject.myMethod = function() {
return "not a number";
};
// 拋出錯(cuò)誤:Method myMethod must return a number在上面的示例中,@myReturnDecorator 裝飾器用于在調(diào)用 myMethod 函數(shù)之后檢查函數(shù)返回值是否為數(shù)字類型。如果返回值不是數(shù)字類型,則拋出錯(cuò)誤。
返回值格式化
裝飾器還可以用于格式化函數(shù)返回值。下面是一個(gè)使用裝飾器格式化函數(shù)返回值的示例:
function myFormatDecorator(target, name, descriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args) {
const result = originalMethod.apply(this, args);
if (typeof result === 'string') {
return result.toUpperCase();
} else {
return result;
}
}
return descriptor;
}
class MyClass {
@myFormatDecorator
myMethod() {
return "hello, world";
}
}
const myObject = new MyClass();
console.log(myObject.myMethod()); // 輸出:HELLO, WORLD在上面的示例中,@myFormatDecorator 裝飾器用于將 myMethod 函數(shù)返回值轉(zhuǎn)換為大寫字母。
裝飾函數(shù)調(diào)用
前置操作
裝飾器可以用于在函數(shù)調(diào)用之前執(zhí)行某些操作。下面是一個(gè)使用裝飾器在函數(shù)調(diào)用之前執(zhí)行某些操作的示例:
function myBeforeDecorator(before) {
return function(target, name, descriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args) {
before();
return originalMethod.apply(this, args);
}
return descriptor;
}
}
class MyClass {
@myBeforeDecorator(() => console.log("before"))
myMethod() {
console.log("myMethod");
}
}
const myObject = new MyClass();
myObject.myMethod();
// 輸出:
// before
// myMethod在上面的示例中,@myBeforeDecorator 裝飾器用于在調(diào)用 myMethod 函數(shù)之前執(zhí)行一個(gè)回調(diào)函數(shù)。
后置操作
裝飾器還可以用于在函數(shù)調(diào)用之后執(zhí)行某些操作。下面是一個(gè)使用裝飾器在函數(shù)調(diào)用之后執(zhí)行某些操作的示例:
function myAfterDecorator(after) {
return function(target, name, descriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args) {
const result = originalMethod.apply(this, args);
after(result);
return result;
}
return descriptor;
}
}
class MyClass {
@myAfterDecorator(result => console.log("after: " + result))
myMethod() {
console.log("myMethod");
return "result";
}
}
const myObject = new MyClass();
console.log(myObject.myMethod());
// 輸出:
// myMethod
// after: result
// result在上面的示例中,@myAfterDecorator 裝飾器用于在調(diào)用 myMethod 函數(shù)之后執(zhí)行一個(gè)回調(diào)函數(shù),將函數(shù)返回值作為參數(shù)傳遞給回調(diào)函數(shù)。
總結(jié)
本文介紹了五個(gè)使用 JavaScript 裝飾器的技巧,包括裝飾函數(shù)參數(shù)、裝飾類屬性、裝飾函數(shù)返回值和裝飾函數(shù)調(diào)用,這5個(gè)不同的JavaScript裝飾器技巧,這些技巧可以讓你的代碼更加美觀、優(yōu)雅和易于閱讀,還可以幫助我們更好地組織代碼和增強(qiáng)擴(kuò)展函數(shù)和類的功能。
以上就是5個(gè)讓你眼前一亮的JavaScript裝飾器技巧的詳細(xì)內(nèi)容,更多關(guān)于JavaScript裝飾器技巧的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
微信小程序-可移動(dòng)菜單的實(shí)現(xiàn)過程詳解
這篇文章主要介紹了微信小程序-可移動(dòng)菜單的實(shí)現(xiàn)過程詳解,我們可以經(jīng)??吹绞謾C(jī)app里有的菜單欄是懸浮在首頁的,用戶可以拖動(dòng)和點(diǎn)擊菜單欄進(jìn)行交互,今天就教大家利用小程序的控件,,需要的朋友可以參考下2019-06-06
JavaScript使用map()方法遍歷數(shù)組并返回新數(shù)組的代碼示例
在 JavaScript 中,數(shù)組是最常用的數(shù)據(jù)結(jié)構(gòu)之一,遍歷數(shù)組以執(zhí)行某種操作是我們開發(fā)中的常見任務(wù),map() 方法是數(shù)組的一個(gè)內(nèi)置方法,本文將詳細(xì)介紹如何使用 map() 方法來遍歷數(shù)組并返回一個(gè)新的數(shù)組,需要的朋友可以參考下2025-06-06
JS正則表達(dá)式驗(yàn)證端口范圍(0-65535)
這篇文章主要介紹了JS正則表達(dá)式驗(yàn)證端口范圍(0-65535),文中給大家提到了Js正則表達(dá)式驗(yàn)證IP+端口號(hào)的代碼,需要的朋友可以參考下2020-01-01
JavaScript?進(jìn)階問題列表(各種js代碼段1-65)
從基礎(chǔ)到進(jìn)階,測(cè)試你有多了解?JavaScript,刷新你的知識(shí),或者幫助你的?coding?面試!?:muscle:?:rocket:?我每周都會(huì)在這個(gè)倉庫下更新新的問題2024-11-11
利用d3.js實(shí)現(xiàn)蜂巢圖表帶動(dòng)畫效果
這篇文章主要給大家介紹了關(guān)于如何利用d3.js實(shí)現(xiàn)蜂巢圖表帶動(dòng)畫效果的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用d3.js具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
JavaScript仿網(wǎng)易選項(xiàng)卡制作代碼
這篇文章主要為大家詳細(xì)介紹了JavaScript仿網(wǎng)易選項(xiàng)卡制作代碼,具有一定的參考價(jià)值,感興趣的朋友可以參考一下2016-10-10

