Array, Set, Object, Map As usual, detailed API additions are provided at the bottom of the article.

You might ask, why compare Object and Map alone, rather than Map, Array, or Object and Set? Different from the other two groups, Map and Object have many similarities which require us to have a deeper understanding and comparison, so as to analyze their more suitable application scenarios respectively.

concept

What is the Map

A Map is a data structure (which, in particular, is an abstract type of data structure) that stores data in pairs containing keys and the values mapped to that key. And because of the uniqueness of keys, there are no duplicate key-value pairs. Maps are designed to quickly search and find data. For example: {(1, “smile”), (2, “cry”), (42, “happy”)}

In a Map, each pair of data is formatted as a key-value pair.

Note: Keys and values in a Map can be any data type, not just strings or integers.

What is the Object

A regular object in JavaScript is a dictionary-type data structure — meaning it still follows the same key-value pair storage structure as a Map. Keys, or attributes, in an Object are also unique and correspond to a single value.

In addition, objects in JavaScript have built-in prototypes. It’s important to note that almost all objects in JavaScript are Object instances, including maps. For example: {1: ‘smile’, 2: ‘cry’, 42: ‘happy’}

By definition, both Objects and maps store data as key-value pairs, but there are substantial differences between them

  • Key: Object follows normal dictionary rules. Keys must be of a single type and can only be integers, strings, or symbols. However, in maps, keys can be of any data type (Object, Array, etc.). (You can try setting an Object as an Object key to see the resulting data structure)
  • Element order: Map preserves the order of all elements, whereas Object does not guarantee the order of attributes. (If in doubt, please refer to: Link)
  • Inheritance: Map is an instance Object of Object, which obviously cannot be an instance Object of Map.
var map = new Map([[1.2], [3.4]]);
console.log(map instanceof Object); //true
var obj = new Object(a);console.log(obj instanceof Map); //false
Copy the code

How to build

Object

Like arrays, the way to define an Object is straightforward:

var obj = {}; / / null objects
var obj = {id: 1.name: "Test object"}; 
//2 keys here: id maps to 1, and name maps to "Test object"
Copy the code

Or use the constructor:

var obj = new Object(a);/ / null objects
var obj = new Object; / / null objects
Copy the code

Or use object.prototype.create

var obj = Object.create(null); / / null objects
Copy the code

Note: You can only use Object.prototype.create in certain situations, such as:

  • You want to inherit from a stereotype object without defining its constructor.
var Vehicle = {
    type: "General".display: function(){console.log(this.type);}
}
var Car = Object.create(Vehicle); // Create an object Car that inherits Vehicle
Car.type = "Car";  // Override the type attribute
Car.display(); //Car
Vehicle.display(); //General
Copy the code

In general, like arrays, avoid using constructors for the following reasons:

  • Constructors write more code
  • Poorer performance
  • More chaotic and more prone to program errors, such as:
var obj = new Object(id: 1.name: "test") // Obvious syntax error

var obj1 = {id: 1.name: "test"};
var obj2 = new Object(obj1); Obj1 and obj2 refer to the same object
obj2.id = 2;
console.log(obj1.id); / / 2
Copy the code

Map

There is only one way to create a Map, using its built-in constructor and new syntax.

var map = new Map(a);//Empty Map
var map = new Map([[1.2], [2.3]]); // map = {1=>2, 2=>3}
Copy the code

Grammar:

Map([iterable])

The Map constructor takes an array or a traversable object as a parameter, and the data in this parameter is key-value pair structure. If it is an array, it contains two elements [key, value].

Access to the elements

  • In the case of maps, methods are used to get elementsMap.prototype.get(key)Implementation, which means we must first know the key that the value corresponds to
map.get(1);
Copy the code
  • Key /property = key/property = key/property;Object. The key > and Object [] 'key'
obj.id / / 1
obj['id'] / / 1
Copy the code
  • Check whether a key exists in the Map
map.has(1);//return boolean value: true/false
Copy the code
  • Object requires some extra judgment
var isExist = obj.id === undefined; 

// or
var isExist = 'id' in obj; // This method checks inherited attributes
Copy the code

Map syntax is similar to Object syntax, but Map syntax is simpler.

Note: we can use the Object. The prototype. The hasOwnProperty () to determine whether there is a specific key Object, the return value is true/false, and will only check on the Object not inherit property.

Insert elements

  • Map supportMap.prototype.set()Method inserts an element. This method takes two arguments: key, value. If an existing key is passed in, the value corresponding to that key is overridden.
map.set(4.5); 
Copy the code
  • Similarly, you can add attributes to an Object using the following method
obj['gender'] = 'female'; //{id: 1, name: "test", gender: "female"}
obj.gender = male; // Override existing attributes
//{id: 1, name: "test", gender: "male"}
Copy the code

As you can see, thanks to their data structure, both methods of inserting elements have O(1) time complexity, and retrieving the key does not require traversing all the data.

Remove elements

Object has no built-in method for deleting elements. We can use the delete syntax:

delete obj.id;
Copy the code

It’s worth noting that a lot of people have asked if it would be better and more performance efficient to use this method.

obj.id = undefined
Copy the code

There is a big logical difference between these two approaches:

  • deleteRemoves a specific property of Object completely
  • useobj[key] = undefinedIt just changes the value of this keyundefinedWhile the property remains in the object.

So when using for… in… The key of the property is still iterated over.

Of course, checking whether an attribute already exists in Object yields two different results in both cases, except for the following checks:

obj.id === undefined; // Same result
Copy the code

Therefore, performance improvements may not be appropriate in some cases.

The delete operator returns a different value, which is true and signals different from any other operator. The delete operator returns true in all cases, unless the property is a non-64x property. Otherwise, it returns false in any non-strict mode, which throws an exception.

Map has more built-in ways to delete elements, such as:

  • delete(key)Used to remove the value of a particular key from a Map. This method returns a Boolean value. Returns if the specified key exists in the target object and was successfully deletedtrue; Returns if the key does not exist in the objectfalse.
var isDeleteSucceeded = map.delete(1);
console.log(isDeleteSucceeded); //true- 
Copy the code
  • clear()Clear all elements in the Map.
map.clear();
Copy the code

Object To implement the Map’s clear() method, you need to iterate through the properties of the Object, deleting them one by one.

Object and Map remove elements in a very similar way. The time complexity of deleting an element is O(1), the time complexity of empting an element is O(n), and n is the size of Object and Map.

Get the size

One advantage of Map over Object is that it can automatically update its size, which can be easily obtained by:

console.log(map.size);
Copy the code

With Object, we need to calculate its size with the object.keys () method, which returns an array containing all the keys.

console.log(Object.keys(obj).length);
Copy the code

Iteration of elements

Map has built-in iterators. Object has no built-in iterators. Add: How do you tell if a type is iterable, which can be done in the following way

/ / typeof < obj > [Symbol. The iterator] = = = "function"
console.log(typeof obj[Symbol.iterator]); //undefined
console.log(typeof map[Symbol.iterator]); //function
Copy the code

In a Map, all elements can be passed through for… Of method traversal:

//For map: { 2 => 3, 4 => 5 }
for (const item of map){
    console.log(item); 
    / / Array [2, 3]
    / / Array (4, 5)
}
//Or
for (const [key,value] of map){
    console.log(`key: ${key}, value: ${value}`);
    //key: 2, value: 3
    //key: 4, value: 5
}
Copy the code

Or use its built-in forEach() method:

map.forEach((value, key) = > console.log(`key: ${key}, value: ${value}`));
//key: 2, value: 3
//key: 4, value: 5
Copy the code

But for Object, we use for… In method

//{id: 1, name: "test"}
for (var key in obj){
   console.log(`key: ${key}, value: ${obj[key]}`);
   //key: id, value: 1
   //key: name, value: test
}
Copy the code

Or use Object.keys(obj) to just get all the keys and iterate

Object.keys(obj).forEach((key) = > console.log(`key: ${key}, value: ${obj[key]}`));
//key: id, value: 1
//key: name, value: test
Copy the code

Ok, so the question is, since they are very similar in structure and performance, Map has more advantages over Object, so should we use Map more often instead of Object?

Application scenarios of Object and Map

Although Map has many advantages over Object, there are still some scenarios where it is better to use Object, which is the most fundamental concept in JavaScript.

  • If you know all the keys, which are strings or integers (or symbols), and you need a simple structure to store the data, Object is a good choice. It is better to build an Object and get elements by knowing a specific key than a Map (literals vs constructors, directly get vsget()Methods).
  • If you want to keep your own logic and attributes in an Object, you can only use Object.
var obj = {
    id: 1.name: "It's Me!".print: function(){ 
        return `Object Id: The ${this.id}, with Name: The ${this.name}`; }}console.log(obj.print());//Object Id: 1, with Name: It's Me.
Copy the code

(You can try using a Map, which doesn’t implement such a data structure.)

  • JSON supports objects directly, but maps are not yet supported. Therefore, in some cases where we must use JSON, Object should be preferred.
  • Map is a pure hash structure, while Object is not (it has its own internal logic). usedeleteDeleting an Object property has many performance problems. Therefore, Map is more suitable for scenarios where a large number of operations are added and deleted.
  • Unlike Object, a Map preserves the order of all elements. The Map structure is built on an iterable basis, so it is better to use Map if you consider element iteration or order, which ensures iterative performance across all browsers.
  • Maps perform better in scenarios where large amounts of data are stored, especially if keys are unknown and all keys and values are of the same type.

conclusion

How you choose objects and maps depends on the data type and operation you are using.

Map has the advantage over Object when all we need is a simple, searchable storage structure, which provides all the basic operations. However, Map cannot replace Object in any sense. After all, in Javascript, Object is not just a normal hash table (so Object should not be used as a normal hash table; it wastes a lot of resources).

Other information links: Object-MDN – Mozilla Map – MDN – Mozilla ES6 Introduction – Ruan Yifeng