Object.assign in JavaScript with Getters, Setters and definePropert

This article introduces the Object.assign, Getter, Setters, and definePropert methods for manipulating element objects in JavaScript. Through the understanding of these concepts, it can help everyone better understand how we use these concepts in project development in JavaScript. These basic concepts are also must-know knowledge points in modern JavaScript development, and mastering them is of great help in improving the quality of project code.

  • Object.assign uses
  • Getters, Setters and definePropert
    • Getter settings
    • Setters setting value
    • Object. defineProperty Method

JavaScript feature Promise function
Use of JavaScript features map, forEach, filter and find with arrow functions
JavaScript Feature Destructuring Syntax
JavaScript features Proxy (proxy) and Reflect (reflection)
JavaScript Features Object.assign with Getters, Setters and definePropert
Using XMLHttpRequest in JavaScript

Object.assign using

When using JavaScript to write application code, we often encounter the need to merge two objects. Objects can be easily merged (consolidated) using Object.assign. When merging objects, if two objects have the same property, its value can be overwritten. Also, Object.assign is not only used to overwrite objects, it can also be used to copy objects. Since Object.assign is a function that is often used in scenarios such as input forms, it is important to understand what it can do. We will introduce the basic operation on Object.assign and illustrate it using the example of holding form values. By looking at an example, it becomes more intuitive to see the function in action for merging objects, making it more intimate.
Merge two objects with the Object.assign function and see what happens when they are merged.

const target = {<!-- --> a: 1, b: 2}
const source = {<!-- --> c: 3, d: 4}
const returnedTarget = Object. assign(target, source);
console. log(target)
console. log(source)
console.log(returnedTarget)
========= Result print ========

{<!-- --> a: 1, b: 2, c: 3, d: 4 }
{<!-- --> c: 3, d: 4 }
{<!-- --> a: 1, b: 2, c: 3, d: 4 }

Running this results in: Object.assign’s first argument, target, is merged with its second argument, source, but the contents of source remain unchanged. In addition, you can see that the merged object is included in the returnedTarget of the return value of Object.assign.

You can see that the return value of Object.assign is target, and returnedTarget is equal to target.

1 Merge of same attributes

If both the target object (target) and the source object (source) have the same property named “b”, when using Object.assign, the property value of the source object will override the property value of the target object. That is, the “b” property in the target object will be overwritten by the “b” property in the source object, and the final result will contain the “b” property value of the source object.

const target = {<!-- --> a: 1, b: 2}
const source = {<!-- --> b: 3, d: 4}
const returnedTarget = Object. assign(target, source);
console. log(target)
console. log(source)
console.log(returnedTarget)
========= Result print ========
{<!-- --> a: 1, b: 3, d: 4 }
{<!-- --> b: 3, d: 4 }
{<!-- --> a: 1, b: 3, d: 4 }

2 Update the elements of the object array

Use Object.assign to replace the attribute value in the element object.

let user = [
{<!-- -->
name : 'zht',
dept: 'Department 1'
},
{<!-- -->
name : 'kaimi',
dept: 'Department 2'
},
];

let user1 = {<!-- -->
name: '张**',
dept: 'Department 1'
}
const returnedTarget = Object. assign(user[1], user1);
console. log(user)
========= Result print ========
[
    {<!-- -->
        "name": "zht",
        "dept": "Dept One"
    },
    {<!-- -->
        "name": "Zhang**",
        "dept": "Dept One"
    }
]

Copy of 3 objects

Object.assign is also often used for copying objects. By passing an empty object as the first argument, a brand new object named “user_clone” can be created. The property values in the new object will be copied from the source object.

let user = [
{<!-- -->
name : 'zht',
dept: 'Department 1'
},
{<!-- -->
name : 'kaimi',
dept: 'Department 2'
},
];
const returnedTarget = Object. assign({<!-- -->}, user);
console.log(returnedTarget)
========= Result print ========
{<!-- -->
    "0": {<!-- -->
        "name": "zht",
        "dept": "Dept One"
    },
    "1": {<!-- -->
        "name": "kaimi",
        "dept": "Dept Two"
    }
}

4 more parameters

The above example Object.assign has only two parameters, but the Object.assign function can accept multiple parameters for merging.

let user = {<!-- -->
  name: "zht",
};

let user_id = {<!-- -->
  id: 1,
};

let dept = {<!-- -->
  dpet: "Department 1",
};
user = Object. assign(user, user_id, dept);
console. log(user);
========= Result print ========
{<!-- -->
    "name": "zht",
    "id": 1,
    "dpet": "Department One"
}

If the merged objects contain properties and values with the same key, they will be replaced in the order of program execution, with the last object overwriting the earlier ones.

let user = {<!-- -->
  id: 0,
};

let user_id_1 = {<!-- -->
  id: 1,
};

let user_id_2 = {<!-- -->
  id: 2,
};

let user_id_3 = {<!-- -->
  id: 3,
};
user = Object.assign(user, user_id_1, user_id_2, user_id_3);
console. log(user);
========= Result print ========
    3

5 Object.assign (form) examples

Object.assign is often used when submitting a form. In the following code, we will illustrate how to use it in a form object that retains input form values. First, prepare the form object, which has two attributes, name and dept, and their initial values are null.

If the input form has a value, we use the input object to receive it. If you want to override the form object with the input object, you can use Object.assign and write the code as follows to override the value of name.

const form = {<!-- -->
name: null,
dpet: null
}
const input = {<!-- -->
name: 'zht'
}
Object. assign(form, input)

Let’s write a different example from the previous one. When the form elements are a bit complicated, the code can be simplified by using Object.assign. For example, to update 3 out of 7 properties at once, you can use Object.assign to override only 3 values.

const form = {<!-- -->
name: null,
dept: null,
id: null,
post: null,
address: null,
phone: null
}

const input = {<!-- -->
name: 'zht',
dept: 'Department 1',
id: 1
}
Object. assign(form, input)
console. log(form)
========= Result print ========
{<!-- -->
    "name": "zht",
    "dept": "Dept One",
    "id": 1,
    "post": null,
    "address": null,
    "phone": null
}

It is also possible to merge more complex nested structures. Next, we set the address address property as a data object for merging.

const form = {<!-- -->
name: null,
dept: null,
id: null,
post: null,
address: null,
phone: null
}
const input = {<!-- -->
name: 'zht',
dept: 'Department 1',
id: 1
}
Object. assign(form, input)
const address = {<!-- -->
address : {<!-- -->
address_1: 'Address 1',
address_2: 'Address 2',
address_3: 'Address 3',
}
}
Object. assign(form, address);
console. log(form)
========= Result print ========
{<!-- -->
    "name": "zht",
    "dept": "Dept One",
    "id": 1,
    "post": null,
    "address": {<!-- -->
        "address_1": "Address 1",
        "address_2": "Address 2",
        "address_3": "Address 3"
    },
    "phone": null
}

Getters, Setters and definePropert

Let’s introduce Getter and Setter and Object.defineProperty in JavaScript. Even if you don’t have the opportunity to use them yourself in the project code, you will often see them when you read library code, source code or documentation. Many times we don’t use them when coding, and our understanding of them is not very clear. I hope that through this article, everyone can understand Getter, Setters and definePropert.

Getter Settings

We first create a data object, and create a fullName method in the data object, which is used to return the name and department name. When using the fullName method, the user object needs to use the syntax fullName() to refer to the fullName.

let user = {<!-- -->
  name: "zht",
  dept: "Department 1",
  fullName: function () {<!-- -->
    return `${<!-- -->this.name} is ${<!-- -->this.dept} employee`;
  },
};
alert(user. fullName());

Now let’s use Getter to re-describe the fullName method in the user object. Many people find it strange when they see how to use it for the first time, but they can define the method in this way.

let user = {<!-- -->
  name: "zht",
  dept: "Department 1",
  get fullName() {<!-- -->
    return `${<!-- -->this.name} is ${<!-- -->this.dept} employee`;
  },
};
alert(user. fullName);

Different from the reference method in the previous example, does not need parentheses during execution, and can be directly referenced as when accessing the attributes of name and dept.

By defining methods as Getters, it is also possible to access it using [] brackets instead of . (dot).

let user = {<!-- -->
  name: "zht",
  dept: "Department 1",
  get fullName() {<!-- -->
    return `${<!-- -->this.name} is ${<!-- -->this.dept} employee`;
  },
};
alert(user["fullName"]);

Setters setting value

Setter is a special function used to set the property value of the object. It can be used to control the assignment process of attributes, so that more flexible attribute access and modification can be achieved. The naming convention for Setter functions is prefixed with “set”, followed by the name of the property to be set. The Setter function can accept a parameter, which is used to set the value of the property

In the following example “set fullName”, we try to set an assignment function for the fullName method of the user object. If the fullName has a Setter function, the Setter function will be called automatically, and the parameter will be passed to the function as a value to complete other business deal with.

let user = {<!-- -->
  name: "zht",
  dept: "Department 1",
  get fullName() {<!-- -->
    return `${<!-- -->this.name} is ${<!-- -->this.dept} employee`;
  },
  set fullName(value) {<!-- -->
    [this.name, this.dept] = value.split(" ");
  },
};
//setter
user.fullName = "kaimi department two";
//getter
alert(user["fullName"]);
========= Result print ========
Kaimi is an employee of Department 2

The same fullName property is used in get and set, but the setter is used when assigning a value using the equals sign “=” and the getter is used when getting the value.

In the setter, it is also possible to check the input string. You can use the match method to check whether there is a space in the input string, and output a message if there is no space.

let user = {<!-- -->
  name: "zht",
  dept: "Department 1",
  get fullName() {<!-- -->
    return `${<!-- -->this.name} is ${<!-- -->this.dept} employee`;
  },
  set fullName(value) {<!-- -->
   if (!value.match(" ")) {<!-- -->
      alert("There is no space in the string");
      return;
    }
    [this.name, this.dept] = value.split(" ");
  },
};
user.fullName = "kaimi department two";
alert(user["fullName"]);
========= Result print ========
no spaces in the string
zht is an employee of department one

Object.defineProperty method

By using Object.defineProperty, you can add Getters and Setters to the defined user object. While the purpose of Object.defineProperty can be inferred from the name and format, using it shouldn’t be too difficult if you already understand Getters and Setters.

In the following code example, Object.defineProperty is used to add a Setter and Getter to the defined user object.

let user = {<!-- -->
  name: "zht",
  dept: "Department 1"
};
Object.defineProperty(user, "fullName", {<!-- -->
  get: function () {<!-- -->
       return `${<!-- -->this.name} is ${<!-- -->this.dept} employee`;
  },
  set: function (value) {<!-- -->
    [this.name, this.dept] = value.split(" ");
  },
});
user.fullName = "kaimi department two";
alert(user["fullName"]);
========= Result print ========
Kaimi is an employee of Department 2

The format of Object.defineProperty is as follows.

  • Object.defineProperty(object, property name, description)

In the above example, the attribute name in the user object corresponds to the fullName of the attribute name used during access, and the descriptor corresponds to the object with get and set.

There are two important properties in Object.defineProperty.

  • enumerable (set get) method switch.
  • Configurable delete delete can be used.

For the get and set methods in Object.defineProperty, we can control whether they will be used by configuring the true or false of the enumerable property. Check what kind of difference exists by setting it to true or false. enumerable is false by default, but you can set it explicitly like this:

let user = {<!-- -->
  name: "zht",
  dept: "Department 1"
};
Object.defineProperty(user, "fullName", {<!-- -->
  get: function () {<!-- -->
       return `${<!-- -->this.name} is ${<!-- -->this.dept} employee`;
  },
  set: function (value) {<!-- -->
    [this.name, this.dept] = value.split(" ");
  },
  enumerable: true
});
//Use a for loop to display the elements defined by Object.defineProperty.
for (key in user) {<!-- -->
  console.log(key);
}
========= Result print ========
{<!-- --> firstName: 'zht', lastName: 'Department One', fullName: 'zht is an employee of Department One' }

Setting enumerable to false will not display the content in fullName.

let user = {<!-- -->
  name: "zht",
  dept: "Department 1"
};
Object.defineProperty(user, "fullName", {<!-- -->
 ?…
  enumerable: false
});
//Use a for loop to display the elements defined by Object.defineProperty.
for (key in user) {<!-- -->
  console.log(key);
}
========= Result print ========
{<!-- --> firstName: 'zht', lastName: 'Department One'}

It also has an important feature that when using Object.assign to merge objects, if the merged object enumerable is true fullName will be merged, but if it is false it will not be included in the merge.

// when enumerable is true
console.log(Object.assign({<!-- -->}, user));
========= Results ========
{<!-- --> firstName: 'zht', lastName: 'Department One', fullName: 'zht is an employee of Department One' }

// when enumerable is false
console.log(Object.assign({<!-- -->}, user));
========= Results ========
{<!-- --> firstName: 'zht', lastName: 'Department One'}

The configurable attribute is to control whether the object attribute can execute the delete command. It is used in the same way as enumerable, and it is false by default. If set to true, it means that the (set, get) methods in the object can be deleted by the delete command. After the method is deleted, calling these deleted methods again will return undefined. If it is false, it means that methods like fullName will not be deleted by the delete command.

let user = {<!-- -->
  name: "zht",
  dept: "Department 1"
};
Object.defineProperty(user, "fullName", {<!-- -->
  get: function () {<!-- -->
       return `${<!-- -->this.name} is ${<!-- -->this.dept} employee`;
  },
  set: function (value) {<!-- -->
    [this.name, this.dept] = value.split(" ");
  },
  enumerable: true,
  configurable: true,
});

//configurable: when true
delete user.fullName;
console.log(user.fullName);
========= Results ========
undefined

//configurable: when false
delete user.fullName;
console.log(user.fullName);
========= Results ========
zht is an employee of department one

Through the above introduction, you will not be able to use them in development, but when these keywords appear in the code, you will also have a better understanding of what the code does. I hope that when you encounter codes with keywords such as Getter, Setter, and Object.defineProperty in the future, you will not be troubled by them anymore.