It is to achieve similar data binding vue with Object.defineProperty.
Object.defineProperty official address
Come to the question:
first step:
Data = const { name: "Tom" , Age: 14 } Object.defineProperty (Data, "name" , { GET () { return "name was read" }, SET (Val) { the console.log ( 'I It is assigned a ' , Val) } }) // this code into the browser console to see the effect console.log (data.name)
The output data.name
is not tom
, but name被读取了
because listeners defineProperty on the name field data were hijacked, modified, name
the value of this field should be returned.
Step two:
const _data = { ...data } for(let i in data){ Object.defineProperty(data, i, { get(){ return _data[i]+"经过了JS的修改" }, set(val){ _data[i] = val; } }) }
Why do we need a separate _data?
Answer: monitor the data fields and modify the field to return the properties, effects of lead is that every time the listener get the field in the data, the browser will call to get the value of the return, if you get in direct return return data[i]
, it would leading to stop calling get the browser to enter into a cycle of death.
Then, to add a bit of data and more data
const data = { name: "tom", age: 14, friend: { "name1": "张三", "name2": "李四", "name3": "王五", "name4": "赵六" }, }
Formatting initial value
createNewWatch = const (Val, path, Parentkey, Event) => { // if the value is not the object type, then this value is returned directly to IF ( typeof Val = 'object'!) return Val; // whereas if the type object, then call WatchObject, during the traversal of sub-elements and monitor // WatchObject will be created in the following code in return WatchObject (Val, path.concat (Parentkey), Event) }
Formatting Object object, the value of listeners
WatchObject = const (Data, path, Event) => { function WatchObject () { for ( var Key in Data) { // call the function previously created format Val Data [Key] = createNewWatch (Data [Key], path , key, Event) // creates a listener for key data Defineproperty ( the this , key, data [key], path.concat (key), Event) } } return new new WatchObject () }
Finally execute code, a simple data monitor is complete.
const b = WatchObject(data,[],{
set(path,val){
console.log(path,val)
}
})