Good decorator source code to learn the second play
This is the 27th day of my participation in Gwen Challenge
preface
Previous article: good decorator source code learning (a) : time
@ Deprecate, @readOnly, @Enumerable, @non64x
deprecate
Used to indicate that the XX API/ method has been deprecated
Use the sample
A warning that the API has been deprecated can be thrown at function execution with a simple @deprecate as follows
Where “deprecate” has the same effect as “deprecated” but a different alias
export { default as deprecate, default as deprecated } from './core/deprecate'
Copy the code
import { deprecate, deprecated } from '.. /index'
class Test {
@deprecate(a)sayHello1() {
console.log('hello 1');
}
@deprecated('API deprecation Warning ')
sayHello2() {
console.log('hello 2');
}
@deprecate('API deprecation Warning ', {url:'https://www.baidu.com'})
sayHello3() {
console.log('hello 3'); }}const t = new Test()
t.sayHello1()
t.sayHello2()
t.sayHello3()
Copy the code
perform
The function structure
Passing in parameters:
- MSG: There is default content
- Options: Further specify document links through url attributes
const DEFAULT_MSG = 'This function will be removed in future versions.';
interfaceOptions{ url? :string
}
export default function deprecate(msg = DEFAULT_MSG, options:Options = {}) {
return function (target, key, descriptor) {}}Copy the code
Finally realize
const DEFAULT_MSG = 'This function will be removed in future versions.';
interfaceOptions{ url? :string
}
export default function deprecate(msg = DEFAULT_MSG, options:Options = {}) {
return function (target, key, descriptor) {
If the object being decorated is not a function, an error is thrown
if (typeofdescriptor.value ! = ='function') {
throw new SyntaxError('Only functions can be marked as deprecated');
}
// Generate method signature (reaction from xx class xx method)
const methodSignature = `${target.constructor.name}#${key}`;
// If the address document on the cable describes the cause, display the address
if (options.url) {
msg += `\n\n See ${options.url} for more details.\n\n`;
}
return {
...descriptor,
value: function deprecationWrapper() {
// Prints a warning message
console.warn(`DEPRECATION ${methodSignature}: ${msg}`);
// Execute the function
return descriptor.value.apply(this.arguments); }}; }}Copy the code
readonly
Makes the specified property read-only, that is, the content of the property cannot be changed after instantiation
Use the sample
Using the following, you can make the target property read-only with a simple @readonly
import { readonly } from '.. /index';
class Test {
hello1(){
console.log('hello1');
}
@readonly
hello2(){
console.log('hello2'); }}const t = new Test();
t.hello1 = function(){
console.log('1');
}
t.hello1()
t.hello2 = function(){
console.log('2');
}
t.hello2()
Copy the code
perform
function
You can change the writable property of a decorator object descriptor to false without passing additional parameters
export default function readonly(target, key, descriptor) {
descriptor.writable = false
return descriptor
}
Copy the code
Enumerable, nonEnumerable, Enumable
Change the enumerable property value of the decorator object
Use the sample
import enumable from ".. /core/enumable";
import enumerable from ".. /core/enumerable";
import nonenumerable from ".. /core/nonenumerable";
class Test {
@nonenumerable
a(){}@enumerable
b(){}@enumable(false)
c(){}}console.log(Object.getOwnPropertyDescriptor(Test.prototype,'a')? .enumerable ===false); // true
console.log(Object.getOwnPropertyDescriptor(Test.prototype,'b')? .enumerable ===true); // true
console.log(Object.getOwnPropertyDescriptor(Test.prototype,'c')? .enumerable ===false); // true
console.log(Object.keys(Test.prototype)); // ['b']
Copy the code
implementation
The easy way to do this is to change the Enumerable value of the decoration object
enumerable
export default function enumerable(target, key, descriptor) {
descriptor.enumerable = true
return descriptor
}
Copy the code
nonenumerable
export default function nonenumerable(target, key, descriptor) {
descriptor.enumerable = false
return descriptor
}
Copy the code
enumable
export default function enumable(v = true) {
return function (target, key, descriptor) {
descriptor.enumerable = v
return descriptor
}
}
Copy the code
nonconfigurable
Sets the decorative object’s 64x property to false
The descriptor of this property can be changed and deleted from the corresponding object only if and if the 64x works without any additional information.
Use the sample
import { nonconfigurable } from ".. /index";
class Test {
@nonconfigurable
a(){}b(){}}let prototype:any = Test.prototype
delete prototype.b
console.log(Object.keys(Test.prototype)); // ['a']
delete prototype.a // Cannot delete property 'a' of #
console.log(Object.keys(Test.prototype));
Copy the code
implementation
This is also a simple way to modify the different value of the decorative object
export default function nonconfigurable(target, key, descriptor) {
descriptor.configurable = false
return descriptor
}
Copy the code
To be continued
The next one will learn:
@mixin
: Blends methods into classes@lazyInitialize
: Initializes target properties only when they are used@debounce
: if you@throttle
: the throttle