Object to expand

In addition to simplifying the properties and methods of objects in ES6, it is worth noting that all property names of objects are treated as strings

Case 1:

Var arr =,6,8,88 [5]; console.log(arr['1']); / / 6Copy the code

Arrays are special objects that are implicitly converted to arr[‘1’] when you use arr[1], so you can print out values

Example 2:

let a = 'hello';
let b = 'world';
let obj = {
    [a + b] : true,
    ['hello' + 'world']: undefined
}
Copy the code

The last value is undefined. For the same attribute, JS will not check the value of the attribute and will directly overwrite it

Example 3:

var myObj = {};
myObj[true] = 'foo';
myObj[3] = 'bar';
myObj[myObj] = 'baz';
console.log(myObj); //{'true':'foo','3':'bar','[object Object]': "baz"}
Copy the code

It’s a string, it’s an implicit conversion to a string (toString)

True and 3 will be changed to the corresponding string by toString method on the prototype. MyObj will be changed to [Object Object] by toString method, so baz can be accessed directly by [Object Object]

console.log(myObj["[object Object]"]); //baz
Copy the code

Example 4:

const a = {a: 1}; const b = {b: 2}; const obj = { [a]: 'valueA', [b]: 'valueB' } console.log(obj); //{[object object]: 'valueB'}, are reference values, can overwrite the value of the problemCopy the code

A: “valueA”, b: “valueB”}.


Gets the name of the object method

const person = {
    sayName(){
        console.log('hello');
    }
}
console.log(person.sayName.name); //sayName
Copy the code

Property descriptor getOwnPropertyDescriptor

There was no way to detect property properties (read-only, traversable, etc.) in ES5, and property descriptors were provided in ES6

let obj = {a: 2};
console.log(Object.getOwnPropertyDescriptor(obj, 'a'));
Copy the code

The attribute passed in is a string

Enumerable: True // Enumerable value: 2 Writable: True // Writable, works without any additional control systemCopy the code

DefineProperty Modifies and adds a new attribute

Object. DefineProperty (OBj, prop, Descriptor), Descriptor Describes item sets and configuration sets

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

This method should be called directly on the Object constructor Object, rather than on any instance of type Object. Because this method is on Object, not Object.prototype, instances cannot be inherited.

let obj = {}; Object.defineProperty(obj, 'a', { value: 2, enumerable: true, configurable: }) obj. A = 3;}) obj. // Silence fails, because it is not writable, this statement fails, but no error is reported; But in strict mode console.log(obj) is reported; //{a: 2} console.log(Object.getOwnPropertyDescriptor(obj, 'a')); delete obj.a; console.log(obj); / / {}Copy the code

Writable, which is set to false, disables any writable device and works without any additional information

Another way of writing:

function defineProperty () {
    var _obj = {};
    Object.defineProperty(_obj, 'a', {
        value: 1
    });
    return _obj;
}
var obj = defineProperty();
console.log(obj);
Copy the code

You can also set several properties: defineProperties

function defineProperty () { var _obj = {}; DefineProperties (_obj, {a: {value: 1, writable: true, Enumerable: true, // Can enumerate different: True // Can configure, operate (delete)}, b: {value: 2}}); return _obj; } var obj = defineProperty(); obj.a = 5; console.log(obj.a); // The value is 1 before writable: true, and cannot be modified. After adding writable, the value is changed to 5Copy the code

Attribute values defined with Object.defineProperty() cannot be modified, deleted, or enumerable by default, except in writable/Enumerable

Configure -> conf/config

Getter/setter values and assignments

Every time a property is defined, it generates a getter and setter mechanism

There are some additional operations that you can set up when you assign and value

Get operation

let obj = {a: 1}; obj.a; The default action for [[Get]] is to find the current attribute, or if not, find the prototypeCopy the code

The put operation

obj.a = 3; // Assign operation [[Put]]Copy the code
  1. Getter or setter
  2. Writable: false, does not allow you to change
  3. The assignment

Getters and setters override the original [[Get]] and [[Set]]

Getter: value function

Var obj = {log: ['example', 'test'], get lastest(){if(this.log.length === 0){return undefined; } return this.log[this.log.length - 1]; } } console.log(obj.lastest); // Access the property, which actually calls the get methodCopy the code

Define getters via defineProperty. Value and writable are not available

var obj = { get a(){ return 2; } } Object.defineProperty(obj, 'b', { get: function)() { return this.a * 2; } enumerable: true, value: 6}}} enumerable: true, value: 6}}Copy the code

Setter: Sets the value function

Var language = {set current(name){this.log.push(name)}, log: []} language.current = 'en';Copy the code

Get and set are usually paired together. You can’t get the function names of get and set directly. You have to get the function names through getOwnPropertyDescriptor

var obj = { get foo(){ return this._a; }, set foo(val){ this._a = val * 2; } } obj.foo = 3; / / set the console operation. The log (obj. Foo); //6 console.log(obj.foo.name); / / undefined, cannot take to name var descriptor = Object. The getOwnPropertyDescriptor (obj, 'foo'); console.log(descriptor.get.name); console.log(descriptor.set.name);Copy the code

Application Scenarios:

<p>0</p>
Copy the code
function defineProperty () {
    var _obj = {};
    var a = 1;

    Object.defineProperties(_obj, {
        a: {
            get () {

            },
            set (newVal) {
                a = newVal;
                var oP = document.getElementsByTagName('p')[0];
                oP.innerHTML = a;
            }
        },
        b: {
            value: 2
        }
    });

    return _obj;
}

var obj = defineProperty();
obj.a = 5;
Copy the code

So you can change the value of the p tag

function defineProperty () { var _obj = {}; var a = 1; Object.defineProperties(_obj, { a: { get () { return 'a\'s value is '+ a + '.'; }, set (newVal) { console.log('The value has been designed a new value ' + a) } }, b: { value: 2 } }); return _obj; } var obj = defineProperty(); obj.a = 5; Console.log (obj.a); //set, 5 is the newVal, but the set does not change the value of a, so a is unchanged console.log(obj.a); //getCopy the code

When we set the values and the values, what we get is

The value has been designed a new value 1
a's value is 1.
Copy the code

Data hijacking refers to the practice of accessing or modifying a property of an object, using a piece of code to intercept the behavior, perform additional operations or modify the return result.

That is, the get program is setting something else so that you can’t get the value, preventing you from getting and typing.

Set the data values globally, extending the logic with get and set methods

Value Default value/writable cannot coexist with set and get.


Operating an array

function DataArr () { var _val = null, _arr = []; Object.defineProperty(this, 'val', { get: function () { return _val; }, set: function(newVal) { _val = newVal; _arr.push({val: _val}); console.log('A new value ' + _val + ' has been pushed to _arr'); }}); this.getArr = function(){ return _arr; } } var dataArr = new DataArr(); dataArr.val = 123; dataArr.val = 234; console.log(dataArr.getArr());Copy the code

Object seal

Object constants: Cannot be deleted or modified

1. Object.defineproperty Configures the attribute descriptor

configurable: false
enumerable: true 
value: 2           
writable: false  
Copy the code

Add the property obj.b=3 normally, and all three values except value are true by default

Add attributes via Object.defineProperty, all three of which are false by default

2. preventExtensions (add new properties or methods)

PreventExtensions cannot change the property descriptor

IsExtensible Determines whether objects are extensible

var obj = {a: 2}; console.log(Object.preventExtensions(obj)); // return the object obj.b = 3; // Silent failure, error console.log(object.isextensible (obj)) in strict mode; //false is not extensibleCopy the code

Still can delete, can modify

3. Object.seal(obj)

Seal changes the signals to false

IsSealed whether it isSealed

var obj = {a: 2};
console.log(Object.seal(obj));
Copy the code

But writable is still true, which means it can be modified

4. Object.freeze(obj)

Freeze sets both the 64x and writable to false. This is just a shallow copy, and to freeze the object deeply, you need to loop through the freeze method

IsFrozen indicates whether the device isFrozen

function myFreeze(obj) { Object.freeze(obj); for(var key in obj) { if (typeof(obj[key]) === 'object' && obj[key] ! == null) { myFreeze(obj[key]); }}}Copy the code

General use freeze


Other methods on the object prototype

Object.is() checks whether the Object is congruent

‘==’ is implicitly converted

The ‘===’ strictly relative operator calls the underlying sameValue algorithm

ES5 To determine whether two values are equal, use an operator to determine

console.log(NaN === NaN); //false
console.log(+0 === -0); //true
Copy the code

ES6 can call the IS method, using ‘===’.

There are only two different outcomes from ES5

console.log(Object.is(NaN, NaN)); //true
console.log(+0 === -0); //false
Copy the code

Keys () gets its own enumerable key name

Object.value() gets its own enumerable key value

Object.entriese() gets its own enumerable key name and value

There are no attributes on the stereotype

coonst foo = {a: 1}; Object.defineProperties(foo, { d: { value: 4, enumerable: true }, f: { value: 5, enumerable: false } }) console.log(Object.keys(foo)); / / / "a", "d", f not enumerated the console. The log (Object. The value of foo ()); / / [1, 4] the console. The log (Object. Entries (foo)); //[["a",1],["d",4]]Copy the code

If the parameter passed in is not an object, it is implicitly converted to wrap the class

let obj = 1; console.log(Object.keys(obj)); / / []Copy the code
let obj = 'abc'; console.log(Object.keys(obj)); / / / "1", "2", "3"]Copy the code

Object.assign(tar, … Sourses) merge objects

Object copy (shallow copy)

let obj = {a: {b: 1}}; let tar = {}; let copy = Object.assign(tar, obj); // The return value is the first argument console.log(copy === tar); //true console.log(copy === obj); //false obj.a.b = 2; console.log(obj.a.b); / / 2Copy the code

Substitutions for attributes of the same name:

const tar = {a: 1, b: 1}; const tar1 = {b: 2, c: 2}; const tar2 = {c: 3}; Object.assign(tar, tar1, tar2); console.log(tar); //{a: 1, b: 2, c: 3Copy the code

Array substitution: Parts of two attributes with the same subscript are replaced

Object. The assign ([1, 2, 3], [4, 5)); / /,5,3 [4]Copy the code

If the value passed is not an object:

Object.assign(undefined, {a: 1}); Var test = object.assign (1, {a: 1}; // To wrap the class, convert to the object console.log(test); //Number{1, a: 1}Copy the code

The first argument must be at least an object. Undefined has no wrapper and cannot be merged

Object.assign({a: 1}, undefined); //{a: 1} Object.assign({a: 1}, 1); //{a: 1} Object.assign({a: 1}, true); //{a: 1} Object.assign({a: 1}, '123'); //{0: "1", 1: "2", 2: "3", a: 1} Object.assign({}, '123', true, 10); //{0: "1", 1: "2", 2: "3"}Copy the code

If the second argument cannot be converted to an object, no processing is done and the object of the first argument is returned

If the second argument is an object, note whether it is enumerable or not

let obj = {a: 1};
Object.defineProperty(obj, 'b', {})
Copy the code

Object.create(proto, [propertiesObject])

The first parameter specifies the stereotype, and the second parameter configures the property and the corresponding descriptor

var obj = Object.create({foo: 1}, { bar: { value: 2 }, baz: { value: 3, enumerable: true } }) console.log(obj); //{baz: 3, bar: 2} let copy = Object.assign({}, obj); console.log(copy); //{baz: 3}, and foo is not copied on the prototypeCopy the code

Inherited properties and non-enumerable properties cannot be copied

Symbol can also be copied using assign. Symbol () generates a completely different, never repeated, primitive type similar to a string

var test = Object.assign({a: b}, {[Symbol('c')] : 'd'});
console.log(test)//{a: "b", Symbol(c): "d"}
Copy the code

Expand on the prototype:

function Person(){}
var age = 1;
Object.assign(Person.prototype, {
    eat(){},
    age,
})
Copy the code

The correct way to override:

const DEFAULT = {
    url: {
        host: 'www.baidu.com',
        port: 7070
    }
}
function test(option){
    option = Object.assign({}, DEFAULT, option);
}
test({url: {port: 8080}})
Copy the code

If the user does not give a value, DEFAULT is used. If the user does, DEFAULT is replaced


Copy value function:

const source = {
    get foo(){
        return 1;
    }
}
const target = {};
Object.assign(target, source); //{foo: 1}
Copy the code

Instead of copying the function itself, you copy the value directly

So instead of using assign, we’re going to use getOwnPropertyDescriptor

Object.defineProperties(tar, Object.getOwnPropertyDescriptor(source));
console.log(Object.getOwnPropertyDescriptor(tar, 'foo'));
Copy the code

This method solves the problem perfectly, and even copies getters and setters


And getOwnPropertyDescriptors shallow copy easily

Using getPropertyOf prototype, getOwnPropertyDescriptors retrieve attributes, and then create the object

const clone = Object.create(Object.getPropertyOf(obj), Object.getOwnPropertyDescriptors(obj));
Copy the code

How objects are deployed

const obj = {a: 1};
Copy the code
const obj = Object.create(port);
Copy the code

We can use assign without get and set

const obj = Object.assign(Object.create(port), {
    foo: 123
})
Copy the code
const obj = Object.create(port, Object.getOwnPropertyDescriptors({
    foo: 123
}));
Copy the code