From 218934fa2ed1c702a6d3923d2aa2cc6b43c48684 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:43:23 -0500 Subject: initial commit --- .../global_objects/array/foreach/index.html | 303 +++++++++++++++++++++ 1 file changed, 303 insertions(+) create mode 100644 files/vi/web/javascript/reference/global_objects/array/foreach/index.html (limited to 'files/vi/web/javascript/reference/global_objects/array/foreach') diff --git a/files/vi/web/javascript/reference/global_objects/array/foreach/index.html b/files/vi/web/javascript/reference/global_objects/array/foreach/index.html new file mode 100644 index 0000000000..6121f40a83 --- /dev/null +++ b/files/vi/web/javascript/reference/global_objects/array/foreach/index.html @@ -0,0 +1,303 @@ +--- +title: Array.prototype.forEach() +slug: Web/JavaScript/Reference/Global_Objects/Array/forEach +translation_of: Web/JavaScript/Reference/Global_Objects/Array/forEach +--- +
{{JSRef}}
+ +

Phương thức forEach() sẽ thực thi một hàm khi duyệt qua từng phần tử của mảng.

+ +
{{EmbedInteractiveExample("pages/js/array-foreach.html")}}
+ + + +

Cú pháp

+ +
arr.forEach(function callback(currentValue[, index[, array]]) {
+    //your iterator
+}[, thisArg]);
+ +

Parameters

+ +
+
callback
+
Hàm sẽ thực thi lên từng phần tử của mảng được gọi, hàm này nhận 3 tham số: +
+
currentValue{{optional_inline}}
+
Giá trị của phần tử đang được duyệt.
+
index{{optional_inline}}
+
Chỉ mục của phần tử đang được duyệt.
+
array{{optional_inline}}
+
Mảng mà hàm forEach() đang duyệt.
+
+
+
thisArg {{Optional_inline}}
+
+

Giá trị được gán cho từ khóa this bên trong hàm callback khi được thực thi.

+
+
+ +

Giá trị trả về

+ +

{{jsxref("undefined")}}.

+ +

Mô tả chi tiết

+ +

forEach() thực thi hàm callback trong lúc duyệt tới từng phần tử của mảng theo thứ tự tăng dần. Nó sẽ không được gọi cho vị trí index đã bị xóa hoặc không được khởi tạo (đối với mảng thưa - sparse arrays).

+ +

callback được gọi với 3 tham số:

+ + + +

Nếu tham số thisArg được truyền vào cho forEach(), nó sẽ được dùng cho từ khóa this trong hàm callback. Nếu không, giá trị {{jsxref("undefined")}} sẽ được dùng cho từ khóa this. Tóm lại, giá trị của từ khóa this trong hàm callback được xác định tuân theo các quy tắc thông thường để xác định this trong một hàm.

+ +

Khoảng các phần tử được xử lý bởi forEach() được thiết lập trước lần gọi đầu tiên của callback. Phần tử được thêm vào mảng sau khi gọi forEach() sẽ không được callback bắt gặp. Nếu giá trị của các phần tử sẵn có trong mảng thay đổi, thì giá trị truyền vào callback sẽ là giá trị lúc forEach() gặp chúng; phần tử bị xoá trước khi bắt gặp sẽ không tính. Nếu phần tử đã gặp rồi bị loại đi (ví dụ dùng {{jsxref("Array.prototype.shift()", "shift()")}}) trong quá trình lặp, các phần tử sau sẽ bị bỏ qua - xem ví dụ phía dưới.

+ +

forEach() executes the callback function once for each array element; unlike {{jsxref("Array.prototype.map()", "map()")}} or {{jsxref("Array.prototype.reduce()", "reduce()")}} it always returns the value {{jsxref("undefined")}} and is not chainable. The typical use case is to execute side effects at the end of a chain.

+ +

forEach() does not mutate the array on which it is called (although callback, if invoked, may do so).

+ +
+

Khác với cú pháp lặp truyền thống, không có cách nào để ngừng vòng lặp forEach ngoài việc ném ra một ngoại lệ. Nếu vì một mục đích nào đó mà bạn cần ngừng vòng lặp thì nên dùng cách khác thay vì dùng forEach

+ +

Một số cách có thể dùng trong trường hợp đó:

+ + + +

Một số hàm khác trên kiểu mảng: {{jsxref("Array.prototype.every()", "every()")}}, {{jsxref("Array.prototype.some()", "some()")}}, {{jsxref("Array.prototype.find()", "find()")}}, and {{jsxref("Array.prototype.findIndex()", "findIndex()")}} test the array elements with a predicate returning a truthy value to determine if further iteration is required.

+
+ +

Ví dụ

+ +

Converting a for loop to forEach

+ +

before

+ +
const items = ['item1', 'item2', 'item3'];
+const copy = [];
+
+for (let i=0; i<items.length; i++) {
+  copy.push(items[i])
+}
+
+ +

after

+ +
const items = ['item1', 'item2', 'item3'];
+const copy = [];
+
+items.forEach(function(item){
+  copy.push(item)
+});
+
+
+ +

Printing the contents of an array

+ +

The following code logs a line for each element in an array:

+ +
function logArrayElements(element, index, array) {
+  console.log('a[' + index + '] = ' + element);
+}
+
+// Notice that index 2 is skipped since there is no item at
+// that position in the array.
+[2, 5, , 9].forEach(logArrayElements);
+// logs:
+// a[0] = 2
+// a[1] = 5
+// a[3] = 9
+
+ +

Using thisArg

+ +

The following (contrived) example updates an object's properties from each entry in the array:

+ +
function Counter() {
+  this.sum = 0;
+  this.count = 0;
+}
+Counter.prototype.add = function(array) {
+  array.forEach(function(entry) {
+    this.sum += entry;
+    ++this.count;
+  }, this);
+  // ^---- Note
+};
+
+const obj = new Counter();
+obj.add([2, 5, 9]);
+obj.count;
+// 3
+obj.sum;
+// 16
+
+ +

Since the thisArg parameter (this) is provided to forEach(), it is passed to callback each time it's invoked, for use as its this value.

+ +
+

If passing the function argument using an arrow function expression the thisArg parameter can be omitted as arrow functions lexically bind the {{jsxref("Operators/this", "this")}} value.

+
+ +

An object copy function

+ +

The following code creates a copy of a given object. There are different ways to create a copy of an object; the following is just one way and is presented to explain how Array.prototype.forEach() works by using ECMAScript 5 Object.* meta property functions.

+ +
function copy(obj) {
+  const copy = Object.create(Object.getPrototypeOf(obj));
+  const propNames = Object.getOwnPropertyNames(obj);
+
+  propNames.forEach(function(name) {
+    const desc = Object.getOwnPropertyDescriptor(obj, name);
+    Object.defineProperty(copy, name, desc);
+  });
+
+  return copy;
+}
+
+const obj1 = { a: 1, b: 2 };
+const obj2 = copy(obj1); // obj2 looks like obj1 now
+
+ +

If the array is modified during iteration, other elements might be skipped.

+ +

The following example logs "one", "two", "four". When the entry containing the value "two" is reached, the first entry of the whole array is shifted off, which results in all remaining entries moving up one position. Because element "four" is now at an earlier position in the array, "three" will be skipped. forEach() does not make a copy of the array before iterating.

+ +
var words = ['one', 'two', 'three', 'four'];
+words.forEach(function(word) {
+  console.log(word);
+  if (word === 'two') {
+    words.shift();
+  }
+});
+// one
+// two
+// four
+
+ +

Polyfill

+ +

forEach() was added to the ECMA-262 standard in the 5th edition; as such it may not be present in other implementations of the standard. You can work around this by inserting the following code at the beginning of your scripts, allowing use of forEach() in implementations that don't natively support it. This algorithm is exactly the one specified in ECMA-262, 5th edition, assuming {{jsxref("Object")}} and {{jsxref("TypeError")}} have their original values and that callback.call() evaluates to the original value of {{jsxref("Function.prototype.call()")}}.

+ +
// Production steps of ECMA-262, Edition 5, 15.4.4.18
+// Reference: http://es5.github.io/#x15.4.4.18
+if (!Array.prototype.forEach) {
+
+  Array.prototype.forEach = function(callback/*, thisArg*/) {
+
+    var T, k;
+
+    if (this == null) {
+      throw new TypeError('this is null or not defined');
+    }
+
+    // 1. Let O be the result of calling toObject() passing the
+    // |this| value as the argument.
+    var O = Object(this);
+
+    // 2. Let lenValue be the result of calling the Get() internal
+    // method of O with the argument "length".
+    // 3. Let len be toUint32(lenValue).
+    var len = O.length >>> 0;
+
+    // 4. If isCallable(callback) is false, throw a TypeError exception.
+    // See: http://es5.github.com/#x9.11
+    if (typeof callback !== 'function') {
+      throw new TypeError(callback + ' is not a function');
+    }
+
+    // 5. If thisArg was supplied, let T be thisArg; else let
+    // T be undefined.
+    if (arguments.length > 1) {
+      T = arguments[1];
+    }
+
+    // 6. Let k be 0.
+    k = 0;
+
+    // 7. Repeat while k < len.
+    while (k < len) {
+
+      var kValue;
+
+      // a. Let Pk be ToString(k).
+      //    This is implicit for LHS operands of the in operator.
+      // b. Let kPresent be the result of calling the HasProperty
+      //    internal method of O with argument Pk.
+      //    This step can be combined with c.
+      // c. If kPresent is true, then
+      if (k in O) {
+
+        // i. Let kValue be the result of calling the Get internal
+        // method of O with argument Pk.
+        kValue = O[k];
+
+        // ii. Call the Call internal method of callback with T as
+        // the this value and argument list containing kValue, k, and O.
+        callback.call(T, kValue, k, O);
+      }
+      // d. Increase k by 1.
+      k++;
+    }
+    // 8. return undefined.
+  };
+}
+
+ +

Đặc tả

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES5.1', '#sec-15.4.4.18', 'Array.prototype.forEach')}}{{Spec2('ES5.1')}}Initial definition. Implemented in JavaScript 1.6.
{{SpecName('ES6', '#sec-array.prototype.foreach', 'Array.prototype.forEach')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-array.prototype.foreach', 'Array.prototype.forEach')}}{{Spec2('ESDraft')}}
+ +

Trình duyệt tương thích

+ +
+ + +

{{Compat("javascript.builtins.Array.forEach")}}

+
+ +

Xem thêm

+ + -- cgit v1.2.3-54-g00ecf