Map

Đối tượng Map lưu cặp key-value (khoá - giá trị) theo thứ tự chèn vào của khoá. Bất kỳ giá trị nào (cả đối tượng (objects) và primitive values) đều có thể sử dụng làm key hoặc value.

Cú pháp

new Map([iterable])

Tham số

iterable
Một Array hoặc iterable object có các phần tử là cặp key-value (các mảng có 2 phần tử, vd. [[ 1, 'one' ],[ 2, 'two' ]]). Mỗi cặp key-value sẽ được thêm vào Map mới; những giá trị null chuyển thành undefined.

Mô tả

Một Map object duyệt qua các phần tử của nó theo thứ tự chèn vào –– một vòng lặp for...of trả về một mảng [key, value] cho mỗi lần lặp.

Key equality (so sánh key)

Key được xác định bằng nhau dựa vào giải thuật "SameValueZero": NaN được xem là giống NaN (mặc dù NaN !== NaN) và tất cả các giá trị khác được xem xét bằng nhau theo toán tử ===. Trong đặc tả ECMAScript hiện tại, -0+0 là bằng nhau, cho dù điều này không đúng ở các bản dự thảo trước đó. Xem "Value equality for -0 and 0" trong bảng tương thích trình duyệt để biết thêm chi tiết.

Objects and maps compared

Objects tương tự với Maps ở chỗ cả hai đều cho phép bạn đặt keys cho values, lấy các values, xoá các keys và xem có gì được chứa trong một key không. Bởi vì điều này (và bởi vì trước đây không tích hợp các lựa chọn khác), trong lịch sử, Objects đã được dùng như Maps; Tuy vậy, có những điểm khác biệt khiến sử dụng một Map thích hợp hơn trong các trường hợp nhất định: 

  • Keys của một Object là StringsSymbols, trong khi chúng có thể là bất kỳ giá trị nào với Map, bao gồm hàm, objects và primitive.
  • Các keys trong Map có thứ tự trong khi các keys trong object thì không. Vì thế, khi duyệt qua, Map object trả về keys theo thứ tự chèn vào.
  • Bạn có thể lấy kích cỡ của một Map dễ dàng qua thuộc tính size, trong khi số thuộc tính trong một Object phải xác định thủ công.
  • Một Map là một iterable và do đó có thể được duyệt trực tiếp, trong khi để duyệt qua một Object cần lấy các keys của nó rồi mới duyệt.
  • Một Object có một prototype, vậy nên có các keys mặc định có thể xung đột với các keys của bạn nếu không cẩn thận. Ở ES5, điều này có thể tránh bằng cách sử dụng map = Object.create(null), nhưng hiếm khi thực hiện.
  • Một Map có thể thực thi tốt hơn ở các hoàn cảnh thường xuyên thêm và xoá các cặp keys.

Các thuộc tính

Map.length
Giá trị của thuộc tính length là 0.
Để lấy số phần tử đang có trong mảng, sử dụng Map.prototype.size (en-US).
get Map[@@species] (en-US)
The constructor function that is used to create derived objects.
Map.prototype (en-US)
Represents the prototype for the Map constructor. Allows the addition of properties to all Map objects.

Map instances

?Tất cả Map instances kế thừa từ Map.prototype (en-US).

Các thuộc tính

{{page('en-US/Web/JavaScript/Reference/Global_Objects/Map/prototype','Properties')}}

Các phương thức

{{page('en-US/Web/JavaScript/Reference/Global_Objects/Map/prototype','Methods')}}

?Ví dụ

Sử dụng Map object

var myMap = new Map();

var keyString = 'a string',
    keyObj = {},
    keyFunc = function() {};

// đặt các values
myMap.set(keyString, "value associated with 'a string'");
myMap.set(keyObj, 'value associated with keyObj');
myMap.set(keyFunc, 'value associated with keyFunc');

myMap.size; // 3

// lấy các values
myMap.get(keyString);    // "value associated with 'a string'"
myMap.get(keyObj);       // "value associated with keyObj"
myMap.get(keyFunc);      // "value associated with keyFunc"

myMap.get('a string');   // "value associated with 'a string'"
                         // ?vì keyString === 'a string'
myMap.get({});           // undefined, vì keyObj !== {}
myMap.get(function() {}) // undefined, vì  keyFunc !== function () {}

Sử dụng NaN làm Map keys

NaN có thể sử dụng làm một key. Kể cả khi mỗi NaN không bằng chính nó (NaN !== NaN trả về true), ví dụ sau chạy tốt bởi vì các NaNs không phân biệt lẫn nhau:

var myMap = new Map();
myMap.set(NaN, 'not a number');

myMap.get(NaN); // "not a number"

var otherNaN = Number('foo');
myMap.get(otherNaN); // "not a number"

Duyệt Maps với for..of

Maps có thể được duyệt với vòng lặp for..of:

var myMap = new Map();
myMap.set(0, 'zero');
myMap.set(1, 'one');
for (var [key, value] of myMap) {
  console.log(key + ' = ' + value);
}
// 0 = zero
// 1 = one

for (var key of myMap.keys()) {
  console.log(key);
}
// 0
// 1

for (var value of myMap.values()) {
  console.log(value);
}
// zero
// one

for (var [key, value] of myMap.entries()) {
  console.log(key + ' = ' + value);
}
// 0 = zero
// 1 = one

Duyệt Maps với forEach()

Maps có thể được duyệt bằng phương thức forEach():

myMap.forEach(function(value, key) {
  console.log(key + ' = ' + value);
});
// Will show 2 logs; first with "0 = zero" and second with "1 = one"

Quan hệ với Array objects

var kvArray = [['key1', 'value1'], ['key2', 'value2']];

// Sử dụng hàm khởi tạo Map để chuyển một 2D key-value Array vào một map
var myMap = new Map(kvArray);

myMap.get('key1'); // returns "value1"

// Sử dụng hàm Array.from để chuyển một map vào một 2D key-value Array
console.log(Array.from(myMap)); // Sẽ hiện ra Array giống hệt kvArray

// Hoặc sử dụng duyệt keys hoặc values và chuyển chúng thành một mảng
console.log(Array.from(myMap.keys())); // Sẽ hiện ["key1", "key2"]

Nhân bản (cloning) và gộp (merging) Maps

Giống như Arrays, Maps có thể được nhân bản:

var original = new Map([
  [1, 'one']
]);

var clone = new Map(original);

console.log(clone.get(1)); // one
console.log(original === clone); // false. Useful for shallow comparison

Keep in mind that the data itself is not cloned

Maps có thể được gộp lại, vẫn đảm bảo các key là duy nhất: 

var first = new Map([
  [1, 'one'],
  [2, 'two'],
  [3, 'three'],
]);

var second = new Map([
  [1, 'uno'],
  [2, 'dos']
]);

// Merge two maps. The last repeated key wins.
// Spread operator essentially converts a Map to an Array
var merged = new Map([...first, ...second]);

console.log(merged.get(1)); // uno
console.log(merged.get(2)); // dos
console.log(merged.get(3)); // three

Maps cũng có thể được gộp với Arrays:

var first = new Map([
  [1, 'one'],
  [2, 'two'],
  [3, 'three'],
]);

var second = new Map([
  [1, 'uno'],
  [2, 'dos']
]);

// Merge maps with an array. The last repeated key wins.
var merged = new Map([...first, ...second, [1, 'eins']]);

console.log(merged.get(1)); // eins
console.log(merged.get(2)); // dos
console.log(merged.get(3)); // three

Các đặc tả

Specification Status Comment
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Map' in that specification.
Standard Initial definition.
ECMAScript (ECMA-262)
The definition of 'Map' in that specification.
Living Standard  

Tương thích trình duyệt

BCD tables only load in the browser

Xem thêm