• Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

preface

We all know that VUe2 implements bidirectional binding based on Object.defineProperty to monitor data changes.

The definition of the Object. DefineProperty ()

The object.defineProperty () method directly defines a new property on an Object, or modifies an existing property of an Object, and returns the Object. Object.defineProperty(obj, prop, descriptor)

Obj: parameter to be defined prop: Attribute name descriptor to be defined or modified Property descriptor to be modified Property descriptor writable

const obj = {}
Object.defineProperty(obj, 'property1', {value:"zz".writable:true});
//writable: Whether it can be modified
obj.property1 = "hh"
console.log(obj);
// {property1:"hh"}
Copy the code

The property descriptor Enumerable

Var obj = {} // Enumerable is set to false and cannot be enumerable. Object.defineProperty(obj,"newKey",{ value:"hello", writable:false, enumerable:false }); For (var attr in obj){console.log(attr); } // Enumerable is true and can be enumerable. Object.defineProperty(obj,"newKey",{ value:"hello", writable:false, enumerable:true }); For (var attr in obj){console.log(attr); //newKey }Copy the code

Property descriptors get,set

const obj = {};
Object.defineProperty(obj, 'property1', {
    get: function () {},set: function (val) {
        console.log(val)
    }
})
obj.property1 = "zz"
console.log(obj)
// {property1:"zz"}
Copy the code

Both get and set functions do not have to be defined. Defining only the fetch function means that the property is read-only and attempts to modify the property are ignored. In strict mode, trying to write a property that defines only the fetch function throws an error. Similarly, only one set function property is unreadable, with undefined returned in non-strict mode and an error thrown in strict mode.

The implementation of a simple version of bidirectional binding

const obj = {}; Object.defineProperty(obj, 'text', { get: function() { console.log('get val'); }, set: function(newVal) { console.log('set val:' + newVal); document.getElementById('input').value = newVal; document.getElementById('span').innerHTML = newVal; }}); const input = document.getElementById('input'); input.addEventListener('keyup', function(e){ obj.text = e.target.value; })Copy the code