diff --git a/test/built-ins/Map/prototype/forEach/callback-parameters.js b/test/built-ins/Map/prototype/forEach/callback-parameters.js
new file mode 100644
index 0000000000000000000000000000000000000000..0688762f8aa1fc9ff575f0cfd645d9a8a685f910
--- /dev/null
+++ b/test/built-ins/Map/prototype/forEach/callback-parameters.js
@@ -0,0 +1,44 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 23.1.3.5
+description: >
+  Verify the parameters order on the given callback.
+info: >
+  Map.prototype.forEach ( callbackfn [ , thisArg ] )
+
+  ...
+  5. If thisArg was supplied, let T be thisArg; else let T be undefined.
+  6. Let entries be the List that is the value of M’s [[MapData]] internal slot.
+  7. Repeat for each Record {[[key]], [[value]]} e that is an element of
+  entries, in original key insertion order
+    a. If e.[[key]] is not empty, then
+      i. Let funcResult be Call(callbackfn, T, «e.[[value]], e.[[key]], M»).
+  ...
+---*/
+
+var map = new Map();
+map.set('foo', 42);
+map.set('bar', 'baz');
+
+var results = [];
+
+var callback = function(value, key, thisArg) {
+  results.push({
+    value: value,
+    key: key,
+    thisArg: thisArg
+  });
+};
+
+map.forEach(callback);
+
+assert.sameValue(results[0].value, 42);
+assert.sameValue(results[0].key, 'foo');
+assert.sameValue(results[0].thisArg, map);
+
+assert.sameValue(results[1].value, 'baz');
+assert.sameValue(results[1].key, 'bar');
+assert.sameValue(results[1].thisArg, map);
+
+assert.sameValue(results.length, 2);
diff --git a/test/built-ins/Map/prototype/forEach/callback-result-is-abrupt.js b/test/built-ins/Map/prototype/forEach/callback-result-is-abrupt.js
new file mode 100644
index 0000000000000000000000000000000000000000..5b31a39bc319b25958a92e46e2b0a064cce8c9dc
--- /dev/null
+++ b/test/built-ins/Map/prototype/forEach/callback-result-is-abrupt.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 23.1.3.5
+description: >
+  Returns error from callback result is abrupt.
+info: >
+  Map.prototype.forEach ( callbackfn [ , thisArg ] )
+
+  ...
+  5. If thisArg was supplied, let T be thisArg; else let T be undefined.
+  6. Let entries be the List that is the value of M’s [[MapData]] internal slot.
+  7. Repeat for each Record {[[key]], [[value]]} e that is an element of
+  entries, in original key insertion order
+    a. If e.[[key]] is not empty, then
+      i. Let funcResult be Call(callbackfn, T, «e.[[value]], e.[[key]], M»).
+      ii. ReturnIfAbrupt(funcResult).
+  ...
+flags: [noStrict]
+---*/
+
+var map = new Map([[0, 0]]);
+
+assert.throws(Test262Error, function() {
+  map.forEach(function() {
+    throw new Test262Error();
+  });
+});
diff --git a/test/built-ins/Map/prototype/forEach/callback-this-non-strict.js b/test/built-ins/Map/prototype/forEach/callback-this-non-strict.js
new file mode 100644
index 0000000000000000000000000000000000000000..d1190b419780fbac5b3bff8eedd3f629906eaa8d
--- /dev/null
+++ b/test/built-ins/Map/prototype/forEach/callback-this-non-strict.js
@@ -0,0 +1,35 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 23.1.3.5
+description: >
+  If a thisArg is not provided, undefined will be used as the this value for
+  each invocation of callbackfn.
+info: >
+  Map.prototype.forEach ( callbackfn [ , thisArg ] )
+
+  ...
+  5. If thisArg was supplied, let T be thisArg; else let T be undefined.
+  6. Let entries be the List that is the value of M’s [[MapData]] internal slot.
+  7. Repeat for each Record {[[key]], [[value]]} e that is an element of
+  entries, in original key insertion order
+    a. If e.[[key]] is not empty, then
+      i. Let funcResult be Call(callbackfn, T, «e.[[value]], e.[[key]], M»).
+  ...
+flags: [noStrict]
+---*/
+
+var _this = [];
+var map = new Map();
+
+map.set(0, 0);
+map.set(1, 1);
+map.set(2, 2);
+
+map.forEach(function() {
+  _this.push(this);
+});
+
+assert.sameValue(_this[0], this);
+assert.sameValue(_this[1], this);
+assert.sameValue(_this[2], this);
diff --git a/test/built-ins/Map/prototype/forEach/callback-this-strict.js b/test/built-ins/Map/prototype/forEach/callback-this-strict.js
new file mode 100644
index 0000000000000000000000000000000000000000..a7f557211d7eb2061773fcfb85572c8ba2bb939d
--- /dev/null
+++ b/test/built-ins/Map/prototype/forEach/callback-this-strict.js
@@ -0,0 +1,35 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 23.1.3.5
+description: >
+  If a thisArg is not provided, undefined will be used as the this value for
+  each invocation of callbackfn.
+info: >
+  Map.prototype.forEach ( callbackfn [ , thisArg ] )
+
+  ...
+  5. If thisArg was supplied, let T be thisArg; else let T be undefined.
+  6. Let entries be the List that is the value of M’s [[MapData]] internal slot.
+  7. Repeat for each Record {[[key]], [[value]]} e that is an element of
+  entries, in original key insertion order
+    a. If e.[[key]] is not empty, then
+      i. Let funcResult be Call(callbackfn, T, «e.[[value]], e.[[key]], M»).
+  ...
+flags: [onlyStrict]
+---*/
+
+var _this = [];
+var map = new Map();
+
+map.set(0, 0);
+map.set(1, 1);
+map.set(2, 2);
+
+map.forEach(function() {
+  _this.push(this);
+});
+
+assert.sameValue(_this[0], undefined);
+assert.sameValue(_this[1], undefined);
+assert.sameValue(_this[2], undefined);
diff --git a/test/built-ins/Map/prototype/forEach/deleted-values-during-foreach.js b/test/built-ins/Map/prototype/forEach/deleted-values-during-foreach.js
new file mode 100644
index 0000000000000000000000000000000000000000..51f70be6f75e8ad320ddebe0285d59608b7467e2
--- /dev/null
+++ b/test/built-ins/Map/prototype/forEach/deleted-values-during-foreach.js
@@ -0,0 +1,41 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 23.1.3.5
+description: >
+  Map state with deleted values during forEach.
+info: >
+  Map.prototype.forEach ( callbackfn [ , thisArg ] )
+
+  ...
+  5. If thisArg was supplied, let T be thisArg; else let T be undefined.
+  6. Let entries be the List that is the value of M’s [[MapData]] internal slot.
+  7. Repeat for each Record {[[key]], [[value]]} e that is an element of
+  entries, in original key insertion order
+    a. If e.[[key]] is not empty, then
+      i. Let funcResult be Call(callbackfn, T, «e.[[value]], e.[[key]], M»).
+      ii. ReturnIfAbrupt(funcResult).
+  ...
+---*/
+
+var map = new Map();
+map.set('foo', 0);
+map.set('bar', 1);
+
+var count = 0;
+var results = [];
+
+map.forEach(function(value, key) {
+  if (count === 0) {
+    map.delete('bar');
+  }
+  results.push({
+    value: value,
+    key: key
+  });
+  count++;
+});
+
+assert.sameValue(results.length, 1);
+assert.sameValue(results[0].key, 'foo');
+assert.sameValue(results[0].value, 0);
diff --git a/test/built-ins/Map/prototype/forEach/does-not-have-mapdata-internal-slot-set.js b/test/built-ins/Map/prototype/forEach/does-not-have-mapdata-internal-slot-set.js
new file mode 100644
index 0000000000000000000000000000000000000000..81c42614a9e280a90f457d280b9cf9ef5830674b
--- /dev/null
+++ b/test/built-ins/Map/prototype/forEach/does-not-have-mapdata-internal-slot-set.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 23.1.3.5
+description: >
+  Throws a TypeError if `this` is a Set object.
+info: >
+  Map.prototype.forEach ( callbackfn [ , thisArg ] )
+
+  ...
+  3. If M does not have a [[MapData]] internal slot, throw a TypeError
+  exception.
+  ...
+features: [Set]
+---*/
+
+assert.throws(TypeError, function() {
+  Map.prototype.forEach.call(new Set(), function() {});
+});
+
+assert.throws(TypeError, function() {
+  var m = new Map();
+  m.forEach.call(new Set(), function() {});
+});
diff --git a/test/built-ins/Map/prototype/forEach/does-not-have-mapdata-internal-slot-weakmap.js b/test/built-ins/Map/prototype/forEach/does-not-have-mapdata-internal-slot-weakmap.js
new file mode 100644
index 0000000000000000000000000000000000000000..551c29bc9ad63d8f454cbaddb557e71db1c8bfd1
--- /dev/null
+++ b/test/built-ins/Map/prototype/forEach/does-not-have-mapdata-internal-slot-weakmap.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 23.1.3.5
+description: >
+  Throws a TypeError if `this` is a WeakMap object.
+info: >
+  Map.prototype.forEach ( callbackfn [ , thisArg ] )
+
+  ...
+  3. If M does not have a [[MapData]] internal slot, throw a TypeError
+  exception.
+  ...
+features: [WeakMap]
+---*/
+
+assert.throws(TypeError, function() {
+  Map.prototype.forEach.call(new WeakMap(), function() {});
+});
+
+assert.throws(TypeError, function() {
+  var m = new Map();
+  m.forEach.call(new WeakMap(), function() {});
+});
diff --git a/test/built-ins/Map/prototype/forEach/does-not-have-mapdata-internal-slot.js b/test/built-ins/Map/prototype/forEach/does-not-have-mapdata-internal-slot.js
new file mode 100644
index 0000000000000000000000000000000000000000..c5035291b159d20d8f6aab5e01056b9e29df8964
--- /dev/null
+++ b/test/built-ins/Map/prototype/forEach/does-not-have-mapdata-internal-slot.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 23.1.3.5
+description: >
+  Throws a TypeError if `this` object does not have a [[MapData]] internal slot.
+info: >
+  Map.prototype.forEach ( callbackfn [ , thisArg ] )
+
+  ...
+  3. If M does not have a [[MapData]] internal slot, throw a TypeError
+  exception.
+  ...
+---*/
+
+var m = new Map();
+
+assert.throws(TypeError, function() {
+  Map.prototype.forEach.call([], function() {});
+});
+
+assert.throws(TypeError, function() {
+  m.forEach.call([], function() {});
+});
+
+assert.throws(TypeError, function() {
+  Map.prototype.forEach.call({}, function() {});
+});
+
+assert.throws(TypeError, function() {
+  m.forEach.call({}, function() {});
+});
diff --git a/test/built-ins/Map/prototype/forEach/first-argument-is-not-callable.js b/test/built-ins/Map/prototype/forEach/first-argument-is-not-callable.js
new file mode 100644
index 0000000000000000000000000000000000000000..996d67b56becb718ec90a1f15b28cdd31b0580b3
--- /dev/null
+++ b/test/built-ins/Map/prototype/forEach/first-argument-is-not-callable.js
@@ -0,0 +1,43 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 23.1.3.5
+description: >
+  Throws a TypeError if first argument is not callable.
+info: >
+  Map.prototype.forEach ( callbackfn [ , thisArg ] )
+
+  4. If IsCallable(callbackfn) is false, throw a TypeError exception.
+  ...
+features: [Symbol]
+---*/
+
+var map = new Map();
+
+assert.throws(TypeError, function() {
+  map.forEach({});
+});
+
+assert.throws(TypeError, function() {
+  map.forEach([]);
+});
+
+assert.throws(TypeError, function() {
+  map.forEach(1);
+});
+
+assert.throws(TypeError, function() {
+  map.forEach('');
+});
+
+assert.throws(TypeError, function() {
+  map.forEach(null);
+});
+
+assert.throws(TypeError, function() {
+  map.forEach(undefined);
+});
+
+assert.throws(TypeError, function() {
+  map.forEach(Symbol());
+});
diff --git a/test/built-ins/Map/prototype/forEach/forEach.js b/test/built-ins/Map/prototype/forEach/forEach.js
new file mode 100644
index 0000000000000000000000000000000000000000..bf80ca900e24b8bfab4c97f8a337ad856eb6a91e
--- /dev/null
+++ b/test/built-ins/Map/prototype/forEach/forEach.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 23.1.3.5
+description: >
+  Property type and descriptor.
+info: >
+  Map.prototype.forEach ( callbackfn [ , thisArg ] )
+
+  17 ECMAScript Standard Built-in Objects
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(
+  typeof Map.prototype.forEach,
+  'function',
+  '`typeof Map.prototype.forEach` is `function`'
+);
+
+verifyNotEnumerable(Map.prototype, 'forEach');
+verifyWritable(Map.prototype, 'forEach');
+verifyConfigurable(Map.prototype, 'forEach');
diff --git a/test/built-ins/Map/prototype/forEach/iterates-in-key-insertion-order.js b/test/built-ins/Map/prototype/forEach/iterates-in-key-insertion-order.js
new file mode 100644
index 0000000000000000000000000000000000000000..36a27cc55f5a1971fcec8111f2331759aff8488d
--- /dev/null
+++ b/test/built-ins/Map/prototype/forEach/iterates-in-key-insertion-order.js
@@ -0,0 +1,51 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 23.1.3.5
+description: >
+  Repeats for each non-empty record, in original key insertion order.
+info: >
+  Map.prototype.forEach ( callbackfn [ , thisArg ] )
+
+  ...
+  5. If thisArg was supplied, let T be thisArg; else let T be undefined.
+  6. Let entries be the List that is the value of M’s [[MapData]] internal slot.
+  7. Repeat for each Record {[[key]], [[value]]} e that is an element of
+  entries, in original key insertion order
+    a. If e.[[key]] is not empty, then
+      i. Let funcResult be Call(callbackfn, T, «e.[[value]], e.[[key]], M»).
+  ...
+---*/
+
+var map = new Map([
+  ['foo', 'valid foo'],
+  ['bar', false],
+  ['baz', 'valid baz']
+]);
+map.set(0, false);
+map.set(1, false);
+map.set(2, 'valid 2');
+map.delete(1);
+map.delete('bar');
+
+// Not setting a new key, just changing the value
+map.set(0, 'valid 0');
+
+var results = [];
+var callback = function(value) {
+  results.push(value);
+};
+
+map.forEach(callback);
+
+assert.sameValue(results[0], 'valid foo');
+assert.sameValue(results[1], 'valid baz');
+assert.sameValue(results[2], 'valid 0');
+assert.sameValue(results[3], 'valid 2');
+assert.sameValue(results.length, 4);
+
+map.clear();
+results = [];
+
+map.forEach(callback);
+assert.sameValue(results.length, 0);
diff --git a/test/built-ins/Map/prototype/forEach/iterates-values-added-after-foreach-begins.js b/test/built-ins/Map/prototype/forEach/iterates-values-added-after-foreach-begins.js
new file mode 100644
index 0000000000000000000000000000000000000000..e398400cc0b5d63f29e427319151e50ba7c38dc7
--- /dev/null
+++ b/test/built-ins/Map/prototype/forEach/iterates-values-added-after-foreach-begins.js
@@ -0,0 +1,49 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 23.1.3.5
+description: >
+  New keys are visited if created during forEach execution.
+info: >
+  Map.prototype.forEach ( callbackfn [ , thisArg ] )
+
+  ...
+  5. If thisArg was supplied, let T be thisArg; else let T be undefined.
+  6. Let entries be the List that is the value of M’s [[MapData]] internal slot.
+  7. Repeat for each Record {[[key]], [[value]]} e that is an element of
+  entries, in original key insertion order
+    a. If e.[[key]] is not empty, then
+      i. Let funcResult be Call(callbackfn, T, «e.[[value]], e.[[key]], M»).
+      ii. ReturnIfAbrupt(funcResult).
+  ...
+---*/
+
+var map = new Map();
+map.set('foo', 0);
+map.set('bar', 1);
+
+var count = 0;
+var results = [];
+
+map.forEach(function(value, key) {
+  if (count === 0) {
+    map.set('baz', 2);
+  }
+  results.push({
+    value: value,
+    key: key
+  });
+  count++;
+});
+
+assert.sameValue(count, 3);
+assert.sameValue(map.size, 3);
+
+assert.sameValue(results[0].key, 'foo');
+assert.sameValue(results[0].value, 0);
+
+assert.sameValue(results[1].key, 'bar');
+assert.sameValue(results[1].value, 1);
+
+assert.sameValue(results[2].key, 'baz');
+assert.sameValue(results[2].value, 2);
diff --git a/test/built-ins/Map/prototype/forEach/iterates-values-deleted-then-readded.js b/test/built-ins/Map/prototype/forEach/iterates-values-deleted-then-readded.js
new file mode 100644
index 0000000000000000000000000000000000000000..0aaaff50944e8c873e8c67616ef007da80fbc83e
--- /dev/null
+++ b/test/built-ins/Map/prototype/forEach/iterates-values-deleted-then-readded.js
@@ -0,0 +1,50 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 23.1.3.5
+description: >
+  New keys are visited if created during forEach execution.
+info: >
+  Map.prototype.forEach ( callbackfn [ , thisArg ] )
+
+  ...
+  5. If thisArg was supplied, let T be thisArg; else let T be undefined.
+  6. Let entries be the List that is the value of M’s [[MapData]] internal slot.
+  7. Repeat for each Record {[[key]], [[value]]} e that is an element of
+  entries, in original key insertion order
+    a. If e.[[key]] is not empty, then
+      i. Let funcResult be Call(callbackfn, T, «e.[[value]], e.[[key]], M»).
+      ii. ReturnIfAbrupt(funcResult).
+  ...
+---*/
+
+var map = new Map();
+map.set('foo', 0);
+map.set('bar', 1);
+
+var count = 0;
+var results = [];
+
+map.forEach(function(value, key) {
+  if (count === 0) {
+    map.delete('foo');
+    map.set('foo', 'baz');
+  }
+  results.push({
+    value: value,
+    key: key
+  });
+  count++;
+});
+
+assert.sameValue(count, 3);
+assert.sameValue(map.size, 2);
+
+assert.sameValue(results[0].key, 'foo');
+assert.sameValue(results[0].value, 0);
+
+assert.sameValue(results[1].key, 'bar');
+assert.sameValue(results[1].value, 1);
+
+assert.sameValue(results[2].key, 'foo');
+assert.sameValue(results[2].value, 'baz');
diff --git a/test/built-ins/Map/prototype/forEach/length.js b/test/built-ins/Map/prototype/forEach/length.js
new file mode 100644
index 0000000000000000000000000000000000000000..3145a46003cdc5a9f2bc9b5c0f6e89b385c571eb
--- /dev/null
+++ b/test/built-ins/Map/prototype/forEach/length.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 23.1.3.5
+description: >
+  Map.prototype.forEach.length value and descriptor.
+info: >
+  Map.prototype.forEach ( callbackfn [ , thisArg ] )
+
+  17 ECMAScript Standard Built-in Objects
+
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(
+  Map.prototype.forEach.length, 1,
+  'The value of `Map.prototype.forEach.length` is `1`'
+);
+
+verifyNotEnumerable(Map.prototype.forEach, 'length');
+verifyNotWritable(Map.prototype.forEach, 'length');
+verifyConfigurable(Map.prototype.forEach, 'length');
diff --git a/test/built-ins/Map/prototype/forEach/name.js b/test/built-ins/Map/prototype/forEach/name.js
new file mode 100644
index 0000000000000000000000000000000000000000..8b4efed913b9deb33ec53ba196f7ea0524b1d325
--- /dev/null
+++ b/test/built-ins/Map/prototype/forEach/name.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 23.1.3.5
+description: >
+  Map.prototype.forEach.name value and descriptor.
+info: >
+  Map.prototype.forEach ( callbackfn [ , thisArg ] )
+
+  17 ECMAScript Standard Built-in Objects
+
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(
+  Map.prototype.forEach.name, 'forEach',
+  'The value of `Map.prototype.forEach.name` is `"forEach"`'
+);
+
+verifyNotEnumerable(Map.prototype.forEach, 'name');
+verifyNotWritable(Map.prototype.forEach, 'name');
+verifyConfigurable(Map.prototype.forEach, 'name');
diff --git a/test/built-ins/Map/prototype/forEach/return-undefined.js b/test/built-ins/Map/prototype/forEach/return-undefined.js
new file mode 100644
index 0000000000000000000000000000000000000000..67f443109ca4738dc39e3160d2d3b5cccdefdb3f
--- /dev/null
+++ b/test/built-ins/Map/prototype/forEach/return-undefined.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 23.1.3.5
+description: >
+  Returns undefined.
+info: >
+  Map.prototype.forEach ( callbackfn [ , thisArg ] )
+
+  ...
+  8. Return undefined.
+---*/
+
+var map = new Map();
+
+var result = map.forEach(function() {
+  return true;
+});
+
+assert.sameValue(result, undefined, 'Empty map#forEach returns undefined');
+
+map.set(1, 1);
+result = map.forEach(function() {
+  return true;
+});
+
+assert.sameValue(result, undefined, 'map#forEach returns undefined');
diff --git a/test/built-ins/Map/prototype/forEach/second-parameter-as-callback-context.js b/test/built-ins/Map/prototype/forEach/second-parameter-as-callback-context.js
new file mode 100644
index 0000000000000000000000000000000000000000..4aec8ce2303df2b29dbe51511c16c57956cf892e
--- /dev/null
+++ b/test/built-ins/Map/prototype/forEach/second-parameter-as-callback-context.js
@@ -0,0 +1,37 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 23.1.3.5
+description: >
+  If a thisArg parameter is provided, it will be used as the this value for each
+  invocation of callbackfn.
+info: >
+  Map.prototype.forEach ( callbackfn [ , thisArg ] )
+
+  ...
+  5. If thisArg was supplied, let T be thisArg; else let T be undefined.
+  6. Let entries be the List that is the value of M’s [[MapData]] internal slot.
+  7. Repeat for each Record {[[key]], [[value]]} e that is an element of
+  entries, in original key insertion order
+    a. If e.[[key]] is not empty, then
+      i. Let funcResult be Call(callbackfn, T, «e.[[value]], e.[[key]], M»).
+  ...
+---*/
+
+var expectedThis = {};
+var _this = [];
+
+var map = new Map();
+map.set(0, 0);
+map.set(1, 1);
+map.set(2, 2);
+
+var callback = function() {
+  _this.push(this);
+};
+
+map.forEach(callback, expectedThis);
+
+assert.sameValue(_this[0], expectedThis);
+assert.sameValue(_this[1], expectedThis);
+assert.sameValue(_this[2], expectedThis);
diff --git a/test/built-ins/Map/prototype/forEach/this-not-object-throw.js b/test/built-ins/Map/prototype/forEach/this-not-object-throw.js
new file mode 100644
index 0000000000000000000000000000000000000000..94edf4ce02710a7b8d44a0e1f998f330268ff1e6
--- /dev/null
+++ b/test/built-ins/Map/prototype/forEach/this-not-object-throw.js
@@ -0,0 +1,43 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 23.1.3.5
+description: >
+  Throws a TypeError if `this` is not an Object.
+info: >
+  Map.prototype.forEach ( callbackfn [ , thisArg ] )
+
+  1. Let M be the this value.
+  2. If Type(M) is not Object, throw a TypeError exception.
+  ...
+features: [Symbol]
+---*/
+
+assert.throws(TypeError, function() {
+  Map.prototype.forEach.call(false, function() {});
+});
+
+assert.throws(TypeError, function() {
+  Map.prototype.forEach.call(1, function() {});
+});
+
+assert.throws(TypeError, function() {
+  Map.prototype.forEach.call('', function() {});
+});
+
+assert.throws(TypeError, function() {
+  Map.prototype.forEach.call(undefined, function() {});
+});
+
+assert.throws(TypeError, function() {
+  Map.prototype.forEach.call(null, function() {});
+});
+
+assert.throws(TypeError, function() {
+  Map.prototype.forEach.call(Symbol(), function() {});
+});
+
+assert.throws(TypeError, function() {
+  var map = new Map();
+  map.forEach.call(false, function() {});
+});