参考资料:都2020年了,你还不会JavaScript 装饰器? 装饰器目前还是提案,新提案似乎还未出来,出来之后可能语法会发生改变,因此装饰器目前用的也不多。浏览器上还无法直接使用。不属于ES6
target:被修饰的类
name:类成员的名字
descriptor:属性描述符,对象会将这个参数传给 Object.defineProperty
// 语法const withSpeak = (targetClass) = {targetClass.speak = 'hello'}@withSpeakclass Student{}cosnt stu = new Student()stu.speak // 'hello'const withLanguage = (language) => (targetClass) => {targetClass.prototype.language = language;}@withLanguage('Chinese')class Student {}const student = new Student();student.language; // 'Chinese'// 类属性装饰器function readonly(target, name, descriptor) {descriptor.writable = false;return descriptor;}class Person {@readonly name = 'person'}const person = new Person();person.name = 'tom';
例子:time装饰器,用来统计一个函数的执行时间,以便于后期做一些性能优化:
function time(target, name, descriptor) {const func = descriptor.value;if (typeof func === 'function') {descriptor.value = function(...args) {console.time();const results = func.apply(this, args);console.timeEnd();return results;}}}class Person {@timesay() {console.log('hello')}}const person = new Person();person.say();
节流throttle:
const throttle = (time) => {let prev = new Date();return (target, name, descriptor) => {const func = descriptor.value;if (typeof func === 'function') {descriptor.value = function(...args) {const now = new Date();if (now - prev > wait) {fn.apply(this, args);prev = new Date();}}}}}// useclass App extends React.Component {componentDidMount() {window.addEveneListener('scroll', this.scroll);}componentWillUnmount() {window.removeEveneListener('scroll', this.scroll);}@throttle(50)scroll() {}}
防抖debounce:
const debounce = (time) => {let timer;return (target, name, descriptor) => {const func = descriptor.value;if (typeof func === 'function') {descriptor.value = function(...args) {if(timer) clearTimeout(timer)timer = setTimeout(()=> {fn.apply(this, args)}, wait)}}}}
core-decorators是一个封装了常用装饰器的 JS 库。
