Object.defineProperty data broker

Posted by The Jackel on Sat, 11 Dec 2021 06:37:44 +0100

If you want to understand data broker, you need to understand a method. This method is on Object. The name of the method is defineproperty(). It is used in many places (such as data hijacking in vue, data broker, and the bottom layer of computing properties)

Define; Property property; So this defineproperty method is used to add properties (or define properties for an object). Since it is used to add properties to an object, I have to have an existing object

let person={
    name: 'Zhang San',
    sex: 'male'
};

I want Zhang San to have an age of 18

Object.defineProperty()

Three parameters are passed:

  • First: which object do you want to add parameters to
  • Second: what is the name of the attribute you added
  • The third is the important parameter (configuration item). The most commonly used parameter is value
Object.defineProperty(person,'age',{
    value: 18
})

After writing this, your person will have an additional age attribute and the value is 18:

console.log(person)

|-{name: 'Zhang San', sex: 'male', age: 18}
|– name: "Zhang San"
|– sex: "male"
|–age: 18
|–[[Prototype]]: Object

This method seems troublesome, but it is more advanced
Use object The properties from defineproperty () cannot be enumerated (not involved in traversal)
First, you need to traverse through another configuration item (enumerable)

Object.defineProperty(person,'age',{
    value: 18,
    enumerable: true //Controls whether attributes can be enumerated. The default value is false
});

If you pass object You can't change a property by defining a property
You can add a configuration item writable

Object.defineProperty(person,'age',{
    value: 18,
    enumerable: true, //Controls whether attributes can be enumerated. The default value is false
    writable: true, //Controls whether the attribute can be modified. The default value is false
});
delete person.Attribute name        Delete attribute

Object. The property in defineproperty() cannot be deleted
To delete, you can use a configuration item, configurable

Object.defineProperty(person,'age',{
    value: 18,
    configurable: true  //Controls whether the attribute can be deleted. The default value is false
});

Define a number=18 in the future. If you want to change the age automatically with the number in the future
The name of the configuration is get, and the value is a function

invoke property getter

  • invoke: mapping
  • property: property
  • getter: refers to the get function
let number = 18;
Object.defineProperty(person,'age',{
    //When someone reads the age attribute of person, the get function (getter) will be called, and the return value is the value of age
    get: function(){
        return number;
    },
});

In addition to get, it has a complementary set

let number = 18;
Object.defineProperty(person,'age',{
    //When someone reads the age attribute of person, the get function (getter) will be called, and the return value is the value of age
    get: function(){
        return number;
    },

    //When someone modifies the age attribute of person, the set function (setter) will be called and the modified specific value will be received
    set(value){
        console.log('Someone modified the value,And the value is',value);
        number = value;
    }
});

number and person are two things, but with the help of object Defineproperty(), the two values are associated

age is retrieved through get() and modified through set

What is a data broker

Data broker: operation (read / write) on attributes in another object through one object broker

//There is an obj with the x attribute; There is also an obj 2. I want to access the x attribute of obj through obj 2, and I hope obj 2 can modify x

let obj = {x:100};
let obj2 = {y:200};

Object.defineProperty(obj2,'x',{
    get(){
        return obj.x
    },
    set(value){
        obj.x = value

    }
})

This is the simplest data broker

Data broker in vue

const vm = new Vue({
    el: '#root',
    data(){
        return{
            name: 'Hangzhou vocational and Technical College',
            address:'Hangzhou'
        }
    }
})

The vm has two name and address attributes, which are added by defineProperty; That is, when someone accesses the name of the vm, the getter works and takes the name of another place for use
If someone modifies the name through vm, the setter will work, but where is this place?
In fact, data() says that there is no other place to configure name, so name and address should have their own setter s and getter s; Indeed

I read the name in the data through vm; Changing name through vm is also the name in data

change: name  --> getter  --->  data.name
 read: name  <-- setter  <---  data.name  
> vm.name       
< 'Hangzhou vocational and Technical College'

The name of data is given to you through the name and getter accessed by vm

name: 'Hangzhou vocational and technical college 123'
> vm.name       
< 'Hangzhou vocational and technical college 123'

It indicates that the getter is indeed from data Name

We change the data of name from vm

> vm.name = 'Hang Zhi'    
< 'Hang Zhi'

Execute vm Name = 'Hangzhi' is to modify the name. In fact, you trigger the setter method of the name attribute on the vm, and then the setter will call data Hangzhou vocational and technical college in name is changed to Hangzhou vocational and technical college to verify whether the name in data has been changed

> data.name
< VM148:1 Uncaught ReferenceError: data is not defined
    at <anonymous>:1:1

The name attribute in data() in the code is not a global variable

The problem is that you can't get the name in data. How can you get it?
The data in the data is finally used by the vm
vm also takes data from data, so it can't lose it. vm will find some ways to save this data. Later, when reading name, getter will work. The problem is where vm saves the data?
The vm itself exists_ Data doesn't want you to open it now because there is data hijacking in it

let data = {
    name: 'Hangzhou vocational and Technical College',
    address:'Hangzhou'
}

const vm = new VUe({
    el: '#root',
    data
})

vm._data = options.data = (outside) data
Validation: VM_ data = data ?

> vm._data === data
< true

Data and in future data_ The data in data is the same meaning

> vm._data.name
< 'Hangzhou vocational and Technical College'
> vm.name = 'Hang Zhi'
< 'Hang Zhi'

The page has changed
You pass vm Name to modify this name must call setter, which causes data Name changes. Once vm detects the change, the page changes

summary

1. Data agent in Vue: agent the operation (read / write) of attributes in data object through vm object
2. Benefits of data broker in Vue: it is more convenient to operate data in data
3. Basic principle: through object Defineproperty () adds all the properties in the data object to the vm. Specify a getter/setter for each property added to the vm. Operate (read / write) the corresponding properties in data within getter/setter*

Topics: Javascript Front-end Vue Vue.js