DefineProperty () Object defineProperty() Object defineProperty()

The title

First two appetizers:

  1. If (a=== 1 && a===2 && a===3) {}, if may execute?
  2. Is there any way to make a defined variable immutable without const?

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.

grammar

Object.defineProperty(obj, prop, descriptor)

parameter

Obj: Object for which attributes are to be defined. Prop: The name or Symbol of the property to be defined or modified. Descriptor: Property descriptor to define or modify.

The descriptor object has six different property values: Value, 64x, Enumerable, value, Writable, GET, and set. The first four are data descriptors and the second two are access descriptors.

If a descriptor has both (value or writable) and (get or set) keys, an exception is raised

  1. The Value attribute

The default is undefined, the value of this property

  • The sample
var o = {};
Object.defineProperty(o, "a", {value: 1
});
console.log(o.a)  / / 1
Copy the code

  1. Writable attribute

The default value is false, indicating whether it can be reassigned

  • The sample
var o = {};
Object.defineProperty(o, "a", {value: 1
    writable: false
});
console.log(o.a);  / / 1
o.a = 2; 
console.log(o.a);  / / 1
Copy the code

Problem 2 above, const problem solved.


  1. Enumerable properties

The default value is false, indicating whether it can be used for… Is traversed in and object. keys methods

  • The sample
var o = {};
Object.defineProperty(o, "a", { value : 1.enumerable: true });
Object.defineProperty(o, "b", { value : 2.enumerable: false });
Object.defineProperty(o, "c", { value : 3 }); // Enumerable defaults to false
o.d = 4; // Enumerable is true if you use direct assignment to create an object property
Object.defineProperty(o, Symbol.for('e'), {
  value: 5.enumerable: true
});
Object.defineProperty(o, Symbol.for('f'), {
  value: 6.enumerable: false
});

for (var i in o) {
  console.log(i);
}
// logs 'a' and 'd' (in undefined order)

Object.keys(o); // ['a', 'd']
Object.getOwnPropertyNames(o);   // ["a", "b", "c", "d"]
Object.getOwnPropertySymbols(o);  // [Symbol(e), Symbol(f)]
Reflect.ownKeys(o);  // ["a", "b", "c", "d", Symbol(e), Symbol(f)]

o.propertyIsEnumerable('a'); // true
o.propertyIsEnumerable('b'); // false
o.propertyIsEnumerable('c'); // false
o.propertyIsEnumerable('d'); // true
o.propertyIsEnumerable(Symbol.for('e')); // true
o.propertyIsEnumerable(Symbol.for('f')); // false

varp = { ... o } p.a/ / 1
p.b // undefined
p.c // undefined
p.d / / 4
p[Symbol.for('e')] / / 5
p[Symbol.for('f')] // undefined
Copy the code

As you can see, getOwnPropertyNames iterates through all non-symbol property values, regardless of whether Enumerable is false


  1. Configurable attributes

The default is false, indicating whether an object’s properties can be deleted and whether features other than value and writable can be modified

  • The sample
var o = {};
Object.defineProperty(o, "a", {value: 1.configurable: false
});
Object.defineProperty(o, 'a', {
  value: 12
});   / / an error

console.log(o.a)  / / 1
o.a = 2;  / / / / is invalid
delete o.a;  / / is invalid
console.log(o.a)  / / 1
Copy the code

  • So the common definition:
var o = {};

o.a = 1;
// Equivalent to:
Object.defineProperty(o, "a", {
  value: 1.writable: true.configurable: true.enumerable: true
});


// On the other hand,
Object.defineProperty(o, "a", { value : 1 });
// Equivalent to:
Object.defineProperty(o, "a", {
  value: 1.writable: false.configurable: false.enumerable: false
});
Copy the code

  1. The Get property

The default value is undefined. This function is called when the property is accessed, and its return value is used as the value of the property

  • The sample
var o = { a: 1 };
Object.defineProperty(o, "a", {
  get: function(){
      console.log("getter");
      return 2}});console.log(o.a);  // getter, 2
Copy the code

  1. The Set properties

The default value is undefined, and this function is called when the property value is modified. This method takes a parameter (that is, the new value assigned to it)

  • The sample
var o = { a: 1 };
Object.defineProperty(o, "a", {
  set: function(newValue){
      console.log("setter",newValue); }}); o.a =2;  // "setter" 2
Copy the code

Question: 1.

var b = 1;  // Avoid redefining b
Object.defineProperty(window."a", {
    get: function(){
        return b++
    }
})
if (a=== 1 && a===2 && a===3 ) {console.log("good")}
Copy the code

Question: 2

var o = {};
Object.defineProperty(o, "a", {value: 1
    writable: false
});
console.log(o.a);  / / 1
o.a = 2;  // Throw an exception
console.log(o.a);  / / 1
Copy the code

In Vue2.0, we also use Object.defineProperty() for dependency collection (Watcher) in get and subscription distribution in set.