Class of
Many object-oriented languages have decorator functions that modify the behavior of a class
@testable
class MyTestableClass{}function testable(target){
target.isTestable = true
}
MyTestableClass.isTestable // true
Copy the code
The above code @testable is testable. It modifies the behavior of the MyTestableClass class by adding the static property isTestable to it. Testable functions target parameters from the MyTestableClass class itself. That is, a decorator is a function that processes a class. The first argument to the decorator function is the target class to be modified
If a parameter is not enough, you can wrap a function around the modifier
function testable(isTestable){
return function(target){
target.isTestable = isTestable
}
}
@testable(true)
class MyTestableClass{}
MyTestableClass.isTestable // true
@testable(false)
class MyTestableClass{}
MyTestableClass.isTestable // false
Copy the code
Modifiers change the behavior of classes at compile time, not run time.
If you want to add instance attributes, you can do so through the Prototype object of the target class
function testable(target){
target.prototype.isTestable = true
}
@testable
class MyTestableClass{}
let obj = new MyTestableClass();
obj.isTestable // true
Copy the code
Method modification
Modifiers can modify not only classes but also class attributes
class Person{
@readonly
name() {return `The ${this.first} The ${this.last}`}}Copy the code
The readonly modifier modifies the name method of the class. The readonly modifier can take three arguments.
function readonly(target, name, descriptor){
The original value of the // Descriptor object is as follows
/ / {
// value: specifiedFunction,
// enumerable: false,
// configurable: true,
// writable: true
// };
descriptor.writable = false;
return descriptor;
}
readonly(Person.prototype, 'name', descriptor)
Copy the code
Prototype. The modifier is intended to modify the instance of the class, but this instance has not been generated yet, so we modify the prototype. The second parameter is the name of the property to be modified, and the third parameter is the description object of the property.
Execution of multiple modifiers
function dec(id){
// This is done in the order of decoration
console.log('evaluated', id);
// The returned functions are executed in reverse order.
return (target, property, descriptor) = > console.log('executed', id)
}
class Example{
@dec(1)
@dec(2)
method(){}
}
// evaluated 1
// evaluated 2
// executed 2
// executed 1
Copy the code
If the same method has multiple modifiers, it will be like peeling an onion, entering from the outside in and then executing from the inside out.
The outer decorator @dec(1) enters first, but the inner decorator @dec(2) executes first.