diff options
Diffstat (limited to 'files/vi/web/javascript/reference/global_objects/array/map/index.html')
-rw-r--r-- | files/vi/web/javascript/reference/global_objects/array/map/index.html | 316 |
1 files changed, 0 insertions, 316 deletions
diff --git a/files/vi/web/javascript/reference/global_objects/array/map/index.html b/files/vi/web/javascript/reference/global_objects/array/map/index.html deleted file mode 100644 index fe3b6c1c37..0000000000 --- a/files/vi/web/javascript/reference/global_objects/array/map/index.html +++ /dev/null @@ -1,316 +0,0 @@ ---- -title: Array.prototype.map() -slug: Web/JavaScript/Reference/Global_Objects/Array/map -translation_of: Web/JavaScript/Reference/Global_Objects/Array/map ---- -<div>{{JSRef}}</div> - -<p>Phương thức <code><strong>map()</strong></code> giúp tạo ra một mảng mới với các phần tử là kết quả từ việc thực thi một hàm lên từng phần tử của mảng được gọi.</p> - -<div>{{EmbedInteractiveExample("pages/js/array-map.html")}}</div> - - - -<h2 id="Cú_pháp">Cú pháp</h2> - -<pre class="syntaxbox"><var>var new_array = arr</var>.map(function <var>callback(currentValue[, index[, array]]) { - // Trả về element mới cho new_array -}</var>[, <var>thisArg</var>])</pre> - -<h3 id="Tham_số">Tham số</h3> - -<dl> - <dt><code>callback</code></dt> - <dd>Hàm để tạo ra phần tử cho mảng mới, nhận vào ba tham số: - <dl> - <dt> </dt> - <dt><code>currentValue</code></dt> - <dd>Giá trị của phần tử trong mảng đang được xử lý</dd> - <dt><code>index</code>{{optional_inline}}</dt> - <dd>Index của phần tử trong mảng đang được xử lý</dd> - <dt><code>array</code>{{optional_inline}}</dt> - <dd>Mảng đang được gọi với <code>map</code></dd> - </dl> - </dd> - <dt><code>thisArg</code>{{optional_inline}}</dt> - <dd>Giá trị gán cho từ khóa <code>this</code> bên trong <code> callback</code>.</dd> -</dl> - -<h3 id="Giá_trị_trả_về">Giá trị trả về</h3> - -<p>Một mảng mới với phần tử là kết quả của hàm <code>callback</code>.</p> - -<h2 id="Mô_tả">Mô tả</h2> - -<p><code>map</code> sẽ gọi hàm <code>callback</code> lên <strong>từng phần tử </strong>của mảng, theo thứ tự trong mảng, và tạo ra một mảng mới chứa các phần tử kết quả. <code>callback</code> chỉ được gọi cho những vị trí index của mảng được gán giá trị, bao gồm cả <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined">undefined</a>. Nó không được gọi cho những vị trí <strong>index trống</strong> (là các index của mảng chưa bao giờ được khởi tạo, bao gồm index chưa được gán giá trị hoặc đã bị xóa bằng <code>delete</code>).</p> - -<p><code>callback</code> được gọi với ba tham số: giá trị của phần tử, index của phần tử, và chính mảng đang được gọi.</p> - -<p>Nếu tham số <code>thisArg</code> được truyền cho <code>map</code>, nó sẽ được gán cho từ khóa <code>this</code> trong hàm callback. Nếu không, giá trị <code>undefined</code> sẽ được dùng cho <code>this</code> với strict mode. Tóm lại, giá trị của từ khóa <code>this</code> trong hàm <code>callback</code> được xác định tuân theo <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this">các quy tắc thông thường để xác định <code>this</code> trong một hàm</a>.</p> - -<p><code>map</code> không làm thay đổi mảng ban đầu mà nó được gọi (mặc dù mảng ban đầu vẫn có thể bị thay đổi trong hàm <code>callback</code>).</p> - -<p>Các phần tử được <code>map()</code> xử lý được xác định từ đầu trước khi <code>callback</code> được gọi lần đầu tiên. Những phần tử mới được thêm vào sau khi <code>map</code> đã bắt đầu chạy sẽ không được <code>callback</code> gọi đến. Trong lúc <code>map</code> đang chạy, nếu những phần tử hiện tại của mảng bị thay đổi, thì giá trị mới của chúng sẽ được truyền cho hàm <code>callback</code> ngay tại thời điểm <code>callback</code> chạy qua. Những phần tử bị xóa sau khi <code>map</code> đã bắt đầu và trước khi đến lượt nó cũng sẽ bị bỏ qua.</p> - -<p>Do thuật toán đã quy định trong đặc tả, nếu như mảng ban đầu đã có sẵn những lỗ trống (index rỗng) thì sau khi được gọi với <code>map</code>, mảng đầu ra cũng sẽ có những index rỗng như mảng ban đầu.</p> - -<h2 id="Ví_dụ">Ví dụ</h2> - -<h3 id="Map_(ánh_xạ)_một_mảng_các_số_thành_một_mảng_các_giá_trị_căn_bậc_hai">Map (ánh xạ) một mảng các số thành một mảng các giá trị căn bậc hai</h3> - -<p>Đoạn code sau sẽ map một mảng các số thành một mảng mới chứa giá trị là căn bậc hai của các số trong mảng ban đầu.</p> - -<pre class="brush: js">var numbers = [1, 4, 9]; -var roots = numbers.map(Math.sqrt); -// mảng roots: [1, 2, 3] -// mảng numbers vẫn là: [1, 4, 9] -</pre> - -<h3 id="Dùng_map_để_format_lại_các_object_trong_mảng">Dùng map để format lại các object trong mảng</h3> - -<p>Đoạn code sau sẽ xử lý một mảng các object và trả về một mảng mới chứa các object đã được format lại:</p> - -<pre class="brush: js">var kvArray = [{key: 1, value: 10}, - {key: 2, value: 20}, - {key: 3, value: 30}]; - -var reformattedArray = kvArray.map(obj =>{ - var rObj = {}; - rObj[obj.key] = obj.value; - return rObj; -}); -// reformattedArray bây giờ là: [{1: 10}, {2: 20}, {3: 30}], - -// kvArray vẫn là: -// [{key: 1, value: 10}, -// {key: 2, value: 20}, -// {key: 3, value: 30}] -</pre> - -<h3 id="Map_một_mảng_các_số_sử_dụng_hàm_có_tham_số">Map một mảng các số sử dụng hàm có tham số</h3> - -<p>Đoạn code sau minh họa cách thức map hoạt động khi <code>callback</code> có sử dụng tham số. Tham số này sẽ có giá trị của từng phần tử của mảng ban đầu khi map duyệt qua mảng này.</p> - -<pre class="brush: js">var numbers = [1, 4, 9]; -var doubles = numbers.map(function(num) { - return num * 2; -}); - -// doubles is now [2, 8, 18] -// numbers is still [1, 4, 9] -</pre> - -<h3 id="Sử_dụng_map_một_cách_độc_lập">Sử dụng <code>map</code> một cách độc lập</h3> - -<p>Ví dụ sau sẽ minh họa cách dùng <code>map</code> lên một {{jsxref("String")}} một cách độc lập để trả về một mảng các mã byte trong bảng ASCII đại diện cho từng ký tự của chuỗi.</p> - -<pre class="brush: js">var map = Array.prototype.map; -var a = map.call('Hello World', function(x) { - return x.charCodeAt(0); -}); -// a now equals [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100] -</pre> - -<h3 id="Sử_dụng_map_với_kết_quả_của_querySelectorAll">Sử dụng <code>map</code> với kết quả của <code>querySelectorAll</code></h3> - -<p>Ví dụ sau minh họa cách duyệt qua một tập các object (không phải mảng) trả về từ <code>querySelectorAll</code>. Trong trường hợp này, chúng ta sẽ in ra giá trị của tất cả các option được chọn (của các thẻ select) lên console: </p> - -<pre class="brush: js">var elems = document.querySelectorAll('select option:checked'); -var values = Array.prototype.map.call(elems, function(obj) { - return obj.value; -}); -</pre> - -<p>Cách trên có thể được giải quyết đơn giản hơn bằng cách sử dụng {{jsxref("Array.from()")}}.</p> - -<h3 id="Trường_hợp_đặc_biệt">Trường hợp đặc biệt</h3> - -<p><a href="http://www.wirfs-brock.com/allen/posts/166">(ý tưởng từ bài viết này)</a></p> - -<p>Chúng ta hay dùng map với hàm một tham số (tham số đó chính là phần tử được duyệt). Và có một số hàm đặc biệt cũng thường được gọi với một tham số, mặc dù chúng có thêm tham số phụ không bắt buộc. Những thói quen này có thể dẫn đến những kết quả ngoài dự đoán.</p> - -<pre class="brush: js" dir="rtl">// Lấy ví dụ: -['1', '2', '3'].map(parseInt); -// Bạn sẽ nghĩ rằng kết quả là [1, 2, 3] -// Nhưng kết quả lại là [1, NaN, NaN] - -// parseInt thường được dùng với 1 tham số, nhưng nó có thể nhận đến 2 tham số. -// Tham số thứ nhất là một biểu thức giá trị và tham số thứ hai là cơ số -// Với hàm callback của Array.prototype.map, nó sẽ nhận vào 3 tham số: -// phần tử, index, mảng ban đầu -// Tham số thứ 3 sẽ được parseInt bỏ qua, nhưng tham số thứ 2 lại có vai trò -// và sẽ dẫn đến kết quả không mong muốn. - -// Sau đây là kết quả thực thi tại từng phần tử: -// parseInt(string, radix) -> map(parseInt(value, index)) -// lần chạy 1 (index là 0): parseInt('1', 0) // cho ta parseInt('1', 0) -> 1 -// lần chạy 2 (index là 1): parseInt('2', 1) // cho ta parseInt('2', 1) -> NaN -// lần chạy 3 (index là 2): parseInt('3', 2) // cho ta parseInt('3', 2) -> NaN - -function returnInt(element) { - return parseInt(element, 10); -} - -['1', '2', '3'].map(returnInt); // [1, 2, 3] -// Thông qua hàm returnInt, kết quả trả về là mảng các số (như mong muốn) - -// Tương tự như trên, nhưng sử dụng một hàm arrow -['1', '2', '3'].map( str => parseInt(str) ); - -// Một cách nữa đơn giản hơn nhưng tránh được vấn đề hàm nhiều tham số: -['1', '2', '3'].map(Number); // [1, 2, 3] -// Tuy nhiên khác với `parseInt`, cách này sẽ giữ lại định dạng -// số thập phân hoặc ký hiệu mũ từ chuỗi ban đầu -['1.1', '2.2e2', '3e300'].map(Number); // [1.1, 220, 3e+300] -</pre> - -<p>Một ví dụ khác khi gọi <code>map</code> với <code>parseInt</code> là tham số cho callback:</p> - -<pre class="brush: js">var xs = ['10', '10', '10']; - -xs = xs.map(parseInt); - -console.log(xs); -// Kết quả trả về là 10,NaN,2 như đã lý giải ở trên.</pre> - -<h2 id="Polyfill">Polyfill</h2> - -<p><code>map()</code> chỉ được thêm vào đặc tả ECMA-262 với phiên bản lần thứ 5; cho nên nó có thể không tồn tại trong một số hiện thực (implementation) của đặc tả. Bạn có thể work around bằng cách thêm vào đoạn code bên dưới vào đầu script của bạn, cho phép sử dụng hàm <code>map</code> tại những nơi mà nó không được hỗ trợ sẵn. Giải thuật trong polyfill này tương đương với hàm <code>map</code> được mô tả trong đặc tả ECMA-262, 5th edition với điều kiện {{jsxref("Object")}}, {{jsxref("TypeError")}}, và {{jsxref("Array")}} không bị thay đổi và <code>callback.call</code> chính là hàm được định nghĩa trong <code>{{jsxref("Function.prototype.call")}}</code>.</p> - -<div class="note"> -<p>Ghi chú bản dịch: những đoạn comment trong code bên dưới trích từ đặc tả ECMA nên sẽ giữ nguyên.</p> -</div> - -<pre><code>// Production steps of ECMA-262, Edition 5, 15.4.4.19 -// Reference: http://es5.github.io/#x15.4.4.19</code> -if (!Array.prototype.map) { - - Array.prototype.map = function(callback/*, thisArg*/) { - - var T, A, 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 A be a new array created as if by the expression new Array(len) - // where Array is the standard built-in constructor with that name and - // len is the value of len. - A = new Array(len); - - // 7. Let k be 0 - k = 0; - - // 8. Repeat, while k < len - while (k < len) { - - var kValue, mappedValue; - - // 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. Let mappedValue be the result of calling the Call internal - // method of callback with T as the this value and argument - // list containing kValue, k, and O. - mappedValue = callback.call(T, kValue, k, O); - - // iii. Call the DefineOwnProperty internal method of A with arguments - // Pk, Property Descriptor - // { Value: mappedValue, - // Writable: true, - // Enumerable: true, - // Configurable: true }, - // and false. - - // In browsers that support Object.defineProperty, use the following: - // Object.defineProperty(A, k, { - // value: mappedValue, - // writable: true, - // enumerable: true, - // configurable: true - // }); - - // For best browser support, use the following: - A[k] = mappedValue; - } - // d. Increase k by 1. - k++; - } - - // 9. return A - return A; - }; -} -</pre> - -<h2 id="Đặc_Tả">Đặc Tả</h2> - -<table class="standard-table"> - <tbody> - <tr> - <th scope="col">Đặc tả</th> - <th scope="col">Trạng thái</th> - <th scope="col">Ghi chú</th> - </tr> - <tr> - <td>{{SpecName('ES5.1', '#sec-15.4.4.19', 'Array.prototype.map')}}</td> - <td>{{Spec2('ES5.1')}}</td> - <td>Định nghĩa lần đầu. Hiện thực trong JavaScript 1.6.</td> - </tr> - <tr> - <td>{{SpecName('ES6', '#sec-array.prototype.map', 'Array.prototype.map')}}</td> - <td>{{Spec2('ES6')}}</td> - <td> </td> - </tr> - <tr> - <td>{{SpecName('ESDraft', '#sec-array.prototype.map', 'Array.prototype.map')}}</td> - <td>{{Spec2('ESDraft')}}</td> - <td> </td> - </tr> - </tbody> -</table> - -<h2 id="Tương_thích_trình_duyệt">Tương thích trình duyệt</h2> - -<div> - - -<p>{{Compat("javascript.builtins.Array.map")}}</p> -</div> - -<h2 id="Xem_thêm">Xem thêm</h2> - -<ul> - <li>{{jsxref("Array.prototype.forEach()")}}</li> - <li>{{jsxref("Map")}} object</li> - <li>{{jsxref("Array.from()")}}</li> -</ul> |