Metaprogramming is a programming technique in which computer programs are written to process other programs as data. This means that you can write programs that can read, generate, analyze, or transform other programs, and even modify the program itself at run time.

In short, metaprogramming can write code like this:

  • You can generate code
  • The language structure can be modified at run time, a phenomenon known as reflection programming or reflection

Several concepts

Symbol

concept

Variables declared with symbol are unique and cannot be repeated

let a1 = Symbol(a)let a2 = Symbol()
a1 === a2 // false

let a3 = Symbol.for('a3')
let a4 = Symbol.for('a3') // The same key is generated only once, and the previous value is fetched each time
a3 === a4 // true
Copy the code

role

let a1 = Symbol.for('abc') // does not conflict with 'ABC'
let obj = {
    [a1]: '123'.'abc': 345.'c': 456
}

// Note: for... Of and the for... In does not get the properties defined by Symbol
Object.getOwnPropertySymbols(obj).forEach(item= > {
   console.log(item) // 123 can only get attributes defined by symbol
})

// Get all attributes containing symbol
Reflect.ownKeys(obj).forEach(item= > {
  console.log(item, obj[item]) 
})
Copy the code

Proxy and Reflect (basically the same API)

Proxy is used to modify the default behavior of certain operations, which is equivalent to making changes at the language level. Therefore, it is a kind of “meta programming”, that is, programming a programming language. — Ruan Yifeng “Introduction to ES6 Standards”

Reflect changes the practice of fetching objects directly with dot syntax and reading them with reflection

Scenarios for Proxy and Reflect

let obj = {
	time: '2021-3-3'.name: 'aaa'._r: 123
}

// Generate a new object through the proxy, and the last user accesses monitor
let monitor = new Proxy(obj, {
    // Intercepts reading of object properties
    get(target, key){}// console.log(monitor.time)
    // Intercepting object setting properties
    set(target, key, value){}// monitor.name = 'a'
    // Intercepts to determine whether an object has an attribute in
    has(target, key){}// Intercepts the delete attribute operation
    deleteProperty(target, key) {
       if (key.indexOf('_') > -1) {
         delete target[key]
         return true
       } else {
       	return target[key]
       }
    }
    / / interception Object. The keys, Object getOwnPropertySymbols, Object. GetOwnPropertyNames
    ownKeys(target) {
    	return Object.keys(target).filter(item= >item ! ='time')}})delete monitor.time
delete monitor._r
Copy the code
let obj = {
    time: '2021-3-3'.name: 'aaa'._r: 123
}
console.log(Reflect.get(obj, 'time') / / 2021-3-3
Reflect.set(obj, 'name'.'Joe')
Reflect.has(obj, 'name') // true
Copy the code

Use proxy and Reflect to implement validation

function validator(target, validator) {
  return new Proxy(target, {
  	_validator: validator,
    set(target
  }
}
Copy the code

Implement forms with metaprogramming

The form, of course, is the name, label, require, validate of the fields, and the conversion of the submitted data.

  • Let’s start by collecting the metadata structure needed for the form
  • With metadata, we can generate the form requirements in a Class
    • initialValues
    • ValidationSchema for data validation
    • Name, label, required, etc. required by each form component
    • The data conversion Handle function submits the form

Segmentfault.com/a/119000000…