5个JavaScript装饰器实用技巧:参数校验、属性保护与调用拦截

作者:半夏

时间:2026-10-30

浏览:339

本文深入解析JavaScript装饰器的五个核心应用场景。通过具体代码示例,演示如何利用装饰器实现函数参数的类型校验与默认值设置、类属性的访问保护与初始化、返回值的类型检查与格式化,以及函数调用前后的前置与后置逻辑拦截。掌握这些技巧有助于编写更健壮、易维护的JavaScript代码。

文章目录

装饰器

什么是装饰器

装饰器本质上是一个函数,它接收一个函数或类作为输入参数,并返回经过修改后的函数或类。在代码中,可以通过 @ 符号将装饰器应用于目标函数或类定义。

下面是一个简单的装饰器示例:

function myDecorator(target) {
  // 对类或函数进行修改
  return target;
}
@myDecorator
class MyClass {
  // 类的定义
}
@myDecorator
function myFunction() {
  // 函数的定义
}

装饰器的作用

装饰器可以应用于多种开发场景,例如:

  • 类属性保护
  • 函数参数类型检查
  • 函数返回值类型检查
  • 函数调用计时

本文将详细介绍如何利用装饰器处理函数参数、类属性、函数返回值以及函数调用过程,通过具体案例展示其实际应用。

装饰函数参数

参数类型检查

利用装饰器可以实现对函数参数类型的严格检查。以下示例展示了如何使用装饰器验证传入参数的类型:

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"); // 抛出错误:Argument 1 is of type string, but should be a string or a number

在上述示例中,@myParameterDecorator 装饰器会在 myMethod 函数执行前,遍历检查所有传入参数是否为字符串或数字类型。若参数类型不符合要求,系统将抛出错误提示。

参数默认值

除了类型检查,装饰器还可用于设定函数参数的默认值。以下示例演示了如何为参数设置默认值:

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 装饰器会检查 myMethod 调用时是否传入了 name 参数。若未传入,则自动使用默认值 "World" 进行后续处理。

装饰类属性

类属性保护

通过装饰器可以有效保护类属性,防止其被意外修改或直接访问。以下示例展示了如何保护类属性:

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;
// 抛出错误:Property myProperty must be a string

在上述示例中,@myPropertyDecorator 装饰器用于保护 MyClass 类的 myProperty 属性。若尝试将该属性赋值为非字符串类型,系统将抛出错误以阻止非法赋值。

类属性初始值

装饰器同样可用于设定类属性的初始值。以下示例展示了如何为属性设置默认初始值:

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 装饰器用于为 MyClass 类的 myProperty 属性设定初始值为 "initial value",确保实例化时拥有确定的初始状态。

装饰函数返回值

返回类型检查

利用装饰器可以验证函数返回值的类型。以下示例展示了如何检查返回值类型:

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";
};
// 抛出错误:Method myMethod must return a number

在上述示例中,@myReturnDecorator 装饰器会在 myMethod 函数执行后,检查其返回值是否为数字类型。若返回值类型不符,系统将抛出错误。

返回值格式化

装饰器还可用于对函数返回值进行格式化处理后返回。以下示例展示了如何格式化返回值:

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 函数的返回值统一转换为大写字母格式后再返回。

装饰函数调用

前置操作

利用装饰器可以在函数正式调用前执行特定的前置操作。以下示例展示了如何在调用前执行操作:

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 装饰器会在 myMethod 函数执行前,先调用一个预定义的回调函数。

后置操作

装饰器同样可用于在函数调用结束后执行特定的后置操作。以下示例展示了如何在调用后执行操作:

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 装饰器会在 myMethod 函数执行后,调用一个回调函数,并将原函数的返回值作为参数传递给该回调函数。

总结

本文介绍了五个使用 JavaScript 装饰器的技巧,包括装饰函数参数、装饰类属性、装饰函数返回值和装饰函数调用,这5个不同的JavaScript装饰器技巧,这些技巧可以让你的代码更加美观、优雅和易于阅读,还可以帮助我们更好地组织代码和增强扩展函数和类的功能。

以上就是5个让你眼前一亮的JavaScript装饰器技巧的详细内容,更多关于JavaScript装饰器技巧的资料请关注本站其它相关文章!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章