JavaScript: mảng và đối tượng Ba bí mật về mảng trong JavaScript có thể bạn chưa biết

  • Dịch
  • I. Lặp lại mảng thực
    1. forEach phương pháp và các phương pháp liên quan
    2. vòng lặp for
    3. Sử dụng đúng cách vòng lặp for...in
    4. vòng lặp for...of (ngầm sử dụng iterator)
    5. Sử dụng rõ ràng iterator
    1. Sử dụng các phương thức để lặp trên mảng thực
    2. Chuyển đổi thành một mảng thực
    3. Lưu ý về các đối tượng thời gian chạy

I. Lặp lại mảng thực

TRÊN khoảnh khắc này Có ba cách để lặp lại các phần tử của một mảng thực:
  1. phương thức Array.prototype.forEach;
  2. vòng lặp for cổ điển
  3. một vòng lặp for...in được xây dựng "chính xác".
Ngoài ra, sắp tới, với sự ra đời của tiêu chuẩn ECMAScript 6 (ES 6) mới, dự kiến ​​sẽ có thêm hai phương pháp:
  1. vòng lặp for...of (ngầm sử dụng iterator);
  2. sử dụng rõ ràng iterator.

1. Phương thức forEach và các phương thức liên quan

Nếu dự án của bạn được thiết kế để hỗ trợ các tính năng của tiêu chuẩn ECMAScript 5 (ES5), bạn có thể sử dụng một trong những cải tiến của nó - phương pháp forEach.

Ví dụ sử dụng:
var a = ["a", "b", "c"]; a.forEach(function(entry) ( console.log(entry); ));
TRONG trường hợp chung việc sử dụng forEach yêu cầu kết nối thư viện mô phỏng es5-shim cho các trình duyệt vốn không hỗ trợ phương pháp này. Chúng bao gồm IE 8 trở lên phiên bản đầu, vẫn còn được sử dụng ở đây và ở đó.

Ưu điểm của forEach là không cần khai báo các biến cục bộ để lưu trữ chỉ mục và giá trị của phần tử mảng hiện tại, vì chúng được tự động truyền vào hàm gọi lại(gọi lại) làm đối số.

Nếu bạn lo lắng về chi phí có thể có khi gọi lại trên từng thành phần, đừng lo lắng và hãy đọc phần này.

ForEach được thiết kế để lặp qua tất cả các phần tử của một mảng, nhưng ngoài ra, ES5 còn cung cấp một số phương thức hữu ích hơn để lặp qua tất cả hoặc một số phần tử đồng thời thực hiện một số hành động trên chúng:

  • each - trả về true nếu đối với mỗi phần tử của mảng, lệnh gọi lại trả về một giá trị có thể được chuyển đổi thành true .
  • some - trả về true nếu đối với ít nhất một phần tử của mảng, lệnh gọi lại trả về một giá trị có thể được chuyển đổi thành true.
  • lọc - tạo mảng mới, bao gồm cả những phần tử đó mảng nguồn, mà lệnh gọi lại trả về true .
  • bản đồ - tạo một mảng mới bao gồm các giá trị được trả về bởi lệnh gọi lại.
  • giảm - giảm một mảng thành một giá trị duy nhất, áp dụng lệnh gọi lại lần lượt cho từng phần tử của mảng, bắt đầu từ phần tử đầu tiên (có thể hữu ích để tính tổng các phần tử mảng và các hàm tóm tắt khác).
  • lessRight - hoạt động tương tự như giảm, nhưng lặp qua các phần tử theo thứ tự ngược lại.

2. Vòng lặp For

Tốt cũ cho các quy tắc:

Var a = ["a", "b", "c"]; chỉ số var; cho (chỉ số = 0; chỉ số< a.length; ++index) { console.log(a); }
Nếu độ dài của mảng không đổi trong suốt vòng lặp và bản thân vòng lặp thuộc về phần mã quan trọng về hiệu năng (điều này khó xảy ra), thì bạn có thể sử dụng phiên bản "tối ưu hơn" để lưu trữ độ dài của mảng :

Var a = ["a", "b", "c"]; chỉ số var, len; for (index = 0, len = a.length; chỉ số< len; ++index) { console.log(a); }
Về lý thuyết, mã này sẽ chạy nhanh hơn mã trước một chút.

Nếu thứ tự của các phần tử không quan trọng, thì bạn có thể tiến xa hơn nữa về mặt tối ưu hóa và loại bỏ biến lưu trữ độ dài của mảng, thay đổi thứ tự tìm kiếm thành ngược lại:

Var a = ["a", "b", "c"]; chỉ số var; for (index = a.length - 1; chỉ mục >= 0; --index) ( console.log(a); )
Tuy nhiên, trong các công cụ JavaScript hiện đại, những trò chơi tối ưu hóa như vậy thường không có ý nghĩa gì.

3. Sử dụng đúng vòng lặp for...in

Nếu bạn được khuyên nên sử dụng vòng lặp for...in, hãy nhớ rằng việc lặp qua các mảng không phải là mục đích của nó. Trái ngược với quan niệm sai lầm phổ biến, vòng lặp for...in không lặp qua các chỉ mục mảng mà thông qua các thuộc tính có thể đếm được của một đối tượng.

Tuy nhiên, trong một số trường hợp, chẳng hạn như lặp lại trên các mảng thưa thớt, for...in có thể hữu ích, miễn là bạn có biện pháp phòng ngừa, như trong ví dụ bên dưới:

// a - mảng thưa var a = ; a = "một"; a = "b"; a = "c"; for (var key in a) ( if (a.hasOwnProperty(key) && /^0$|^\d*$/.test(key) && key<= 4294967294) { console.log(a); } }
Trong ví dụ này, hai lần kiểm tra được thực hiện ở mỗi lần lặp của vòng lặp:

  1. mảng có thuộc tính riêng được gọi là khóa (không được kế thừa từ nguyên mẫu của nó).
  2. khóa đó là một chuỗi chứa biểu diễn thập phân của một số nguyên có giá trị nhỏ hơn 4294967294 . Số cuối cùng đến từ đâu? Từ định nghĩa chỉ mục mảng trong ES5, cho thấy chỉ mục cao nhất mà một phần tử trong mảng có thể có là: (2^32 - 2) = 4294967294 .
Tất nhiên, việc kiểm tra như vậy sẽ tốn thời gian không cần thiết khi thực hiện vòng lặp. Nhưng trong trường hợp mảng thưa thớt, phương pháp này hiệu quả hơn vòng lặp for, vì trong trường hợp này chỉ những phần tử được xác định rõ ràng trong mảng mới được lặp lại. Vì vậy, trong ví dụ trên, chỉ có 3 lần lặp sẽ được thực hiện (đối với các chỉ mục 0, 10 và 10000) - so với 10001 trong vòng lặp for.

Để không phải viết mã kiểm tra rườm rà như vậy mỗi khi cần lặp qua một mảng, bạn có thể viết nó dưới dạng một hàm riêng biệt:

Hàm arrayHasOwnIndex(array, key) ( return array.hasOwnProperty(key) && /^0$|^\d*$/.test(key) && key<= 4294967294; }
Khi đó phần thân của vòng lặp trong ví dụ sẽ được giảm đi đáng kể:

For (key in a) ( if (arrayHasOwnIndex(a, key)) ( console.log(a); ) )
Mã kiểm tra được thảo luận ở trên có tính phổ quát, phù hợp với mọi trường hợp. Nhưng thay vào đó, bạn có thể sử dụng một phiên bản ngắn hơn, mặc dù về mặt hình thức không hoàn toàn chính xác nhưng vẫn phù hợp với hầu hết các trường hợp:

For (key in a) ( if (a.hasOwnProperty(key) && String(parseInt(key, 10)) === key) ( console.log(a); ) )

4. Vòng lặp For...of (ngầm sử dụng iterator)

ES6, vẫn ở trạng thái phác thảo, sẽ giới thiệu các trình vòng lặp cho JavaScript.

Trình vòng lặp là một giao thức được thực hiện bởi một đối tượng xác định một cách tiêu chuẩn để thu được một chuỗi các giá trị (hữu hạn hoặc vô hạn).
Trình vòng lặp là một đối tượng xác định phương thức next() - một hàm không có đối số trả về một đối tượng có hai thuộc tính:

  1. done (boolean) - đúng nếu trình lặp đã đạt đến cuối chuỗi lặp. Nếu không thì giá trị là sai.
  2. value - xác định giá trị được trả về bởi iterator. Có thể không được xác định (thiếu) nếu thuộc tính done là true.
Nhiều đối tượng tích hợp, bao gồm. mảng thực có các vòng lặp theo mặc định. Cách đơn giản nhất để sử dụng trình vòng lặp trên mảng thực là sử dụng cấu trúc for...of mới.

Ví dụ về việc sử dụng for...of:

Varval; var a = ["a", "b", "c"]; for (val of a) ( console.log(val); )
Trong ví dụ trên, vòng lặp for...of ngầm gọi trình vòng lặp của đối tượng Array để lấy từng giá trị của mảng.

5. Sử dụng rõ ràng iterator

Các vòng lặp cũng có thể được sử dụng một cách rõ ràng, tuy nhiên, trong trường hợp này, mã trở nên phức tạp hơn nhiều so với vòng lặp for...of. Nó trông giống như thế này:

Var a = ["a", "b", "c"]; var it = a.entries(); mục nhập var; while (!(entry = it.next()).done) ( console.log(entry.value); )
Trong ví dụ này, phương thức Array.prototype.entries trả về một iterator được sử dụng để hiển thị các giá trị của mảng. Ở mỗi lần lặp, entry.value chứa một mảng có dạng [key, value] .

II. Lặp lại các đối tượng giống như mảng

Ngoài mảng thực, trong JavaScript còn có các đối tượng dạng mảng . Điểm chung của chúng với mảng thực là chúng có thuộc tính độ dài và các thuộc tính được đặt tên là số tương ứng với các phần tử của mảng. Các ví dụ bao gồm DOM của bộ sưu tập NodeList và mảng giả đối số, có sẵn bên trong bất kỳ hàm/phương thức nào.

1. Sử dụng các phương thức để lặp trên mảng thực

Ở mức tối thiểu, hầu hết, nếu không phải tất cả, các phương pháp lặp trên mảng thực có thể được sử dụng để lặp trên các đối tượng giống mảng.

Các cấu trúc for và for...in có thể được áp dụng cho các đối tượng giống mảng theo cách giống hệt như cách chúng được áp dụng cho các mảng thực.

ForEach và các phương thức Array.prototype khác cũng áp dụng cho các đối tượng giống mảng. Để làm điều này bạn cần sử dụng Function.call hoặc Function.apply.

Ví dụ: nếu bạn muốn áp dụng forEach cho thuộc tính childNodes của đối tượng Node, bạn sẽ làm như sau:

Array.prototype.forEach.call(node.childNodes, function(child) ( // làm gì đó với đối tượng con));
Để sử dụng lại thủ thuật này dễ dàng hơn, bạn có thể khai báo một tham chiếu đến phương thức Array.prototype.forEach trong một biến riêng biệt và sử dụng nó làm lối tắt:

// (Giả sử tất cả các mã bên dưới nằm trong cùng phạm vi) var forEach = Array.prototype.forEach; // ... forEach.call(node.childNodes, function(child) ( // làm gì đó với đối tượng con));
Nếu một đối tượng giống mảng có một trình vòng lặp, nó có thể được sử dụng một cách rõ ràng hoặc ngầm định để lặp lại đối tượng theo cách tương tự như đối với các mảng thực.

2. Chuyển đổi sang mảng thực

Ngoài ra còn có một cách khác rất đơn giản để lặp qua một đối tượng giống mảng: chuyển đổi nó thành một mảng thực và sử dụng bất kỳ phương thức nào được thảo luận ở trên để lặp qua các mảng thực. Để chuyển đổi, bạn có thể sử dụng phương thức chung Array.prototype.slice, phương thức này có thể được áp dụng cho bất kỳ đối tượng giống mảng nào. Việc này được thực hiện rất đơn giản, như trong ví dụ dưới đây:

Var trueArray = Array.prototype.slice.call(arrayLikeObject, 0);
Ví dụ: nếu bạn muốn chuyển đổi bộ sưu tập NodeList thành một mảng thực tế, bạn cần mã như thế này:

Var divs = Array.prototype.slice.call(document.querySelectorAll("div"), 0);
Cập nhật: Như đã lưu ý trong các ý kiến

Mảng

Mảng là một tập hợp các giá trị có thứ tự. Các giá trị trong một mảng được gọi là các phần tử, mỗi phần tử được đặc trưng bởi một vị trí số trong mảng, được gọi là chỉ mục. Mảng trong JavaScript không được định kiểu: các phần tử của một mảng có thể thuộc bất kỳ loại nào và các phần tử khác nhau của cùng một mảng có thể có các kiểu khác nhau. Các phần tử mảng thậm chí có thể là đối tượng hoặc các mảng khác, cho phép bạn tạo các cấu trúc dữ liệu phức tạp như mảng đối tượng và mảng mảng.

Các chỉ mục mảng JavaScript bắt đầu từ 0 và sử dụng số nguyên 32 bit - phần tử đầu tiên của mảng có chỉ mục 0. Mảng JavaScript rất linh hoạt: chúng có thể tăng và giảm kích thước khi cần thiết; không cần phải khai báo kích thước mảng cố định khi tạo chúng hoặc phân bổ lại bộ nhớ khi kích thước của chúng thay đổi.

Mảng trong JavaScript là một dạng đối tượng chuyên biệt và các chỉ mục mảng không có ý nghĩa gì nhiều ngoài tên thuộc tính, trùng hợp là các số nguyên.

Tạo mảng

Cách dễ nhất để tạo một mảng là sử dụng một hằng, là một danh sách đơn giản gồm các phần tử mảng được phân tách bằng dấu phẩy được bao quanh bởi dấu ngoặc vuông. Các giá trị trong một hằng mảng không nhất thiết phải là hằng số - chúng có thể là bất kỳ biểu thức nào, bao gồm cả các hằng đối tượng:

Var trống = ; // Mảng trống var number = ; // Mảng 5 phần tử số var misc = [ 1.1, true, "a", ]; // 3 phần tử thuộc các loại khác nhau + dấu phẩy ở cuối var base = 1024; bảng var = ; // Mảng chứa các biến var arrObj = [, ]; // 2 mảng bên trong chứa các đối tượng

Cú pháp mảng bằng chữ cho phép bạn chèn dấu phẩy ở cuối tùy chọn, tức là. chữ [,] khớp với một mảng có hai phần tử chứ không phải ba phần tử.

Một cách khác để tạo mảng là gọi hàm tạo Mảng(). Bạn có thể gọi hàm tạo theo ba cách khác nhau:

    Gọi hàm tạo không có đối số:

    Var Array = new Array();

    Trong trường hợp này, một mảng trống sẽ được tạo, tương đương với mảng bằng chữ.

    Gọi hàm tạo với một đối số số duy nhất xác định độ dài của mảng:

    Var Array = Mảng mới(10);

    Trong trường hợp này, một mảng trống có độ dài được chỉ định sẽ được tạo. Hình thức gọi hàm tạo Array() này có thể được sử dụng để phân bổ trước bộ nhớ cho một mảng nếu biết trước số phần tử của nó. Lưu ý rằng điều này không lưu trữ bất kỳ giá trị nào trong mảng.

    Chỉ định rõ ràng các giá trị của hai phần tử mảng trở lên đầu tiên hoặc một phần tử không phải là số trong lệnh gọi hàm tạo:

    Var Array = new Array(5, 4, 3, 2, 1, "test");

    Trong trường hợp này, các đối số của hàm tạo trở thành giá trị của các phần tử của mảng mới. Sử dụng hằng mảng hầu như luôn dễ dàng hơn so với sử dụng hàm tạo Array().

Đọc và viết các phần tử mảng

Các phần tử mảng được truy cập bằng toán tử. Ở bên trái dấu ngoặc phải có tham chiếu mảng. Bên trong dấu ngoặc đơn phải có một biểu thức tùy ý trả về giá trị nguyên không âm. Cú pháp này hữu ích cho cả việc đọc và ghi giá trị của một phần tử mảng. Do đó, tất cả các hướng dẫn JavaScript sau đây đều hợp lệ:

// Tạo một mảng có một phần tử var arr = ["world"]; // Đọc phần tử 0 var value = arr; // Ghi giá trị vào phần tử 1 arr = 3.14; // Ghi giá trị vào phần tử 2 i = 2; mảng[i] = 3; // Ghi giá trị vào phần tử 3 arr = "hello"; // Đọc phần tử 0 và 2, ghi giá trị vào phần tử 3 arr] = arr;

Hãy để tôi nhắc bạn rằng mảng là một loại đối tượng chuyên biệt. Dấu ngoặc vuông dùng để truy cập các phần tử mảng hoạt động giống hệt như dấu ngoặc vuông dùng để truy cập các thuộc tính đối tượng. Trình thông dịch JavaScript chuyển đổi chỉ mục số trong dấu ngoặc đơn thành chuỗi—chỉ mục 1 trở thành chuỗi "1"—và sau đó sử dụng chuỗi làm tên thuộc tính.

Không có gì đặc biệt khi chuyển đổi chỉ mục số thành chuỗi: bạn có thể thực hiện tương tự với các đối tượng thông thường:

Var obj = (); // Tạo một đối tượng đơn giản obj = "one"; // Lập chỉ mục nó bằng số nguyên

Vấn đề về mảng là khi bạn sử dụng tên thuộc tính là số nguyên không âm, mảng sẽ tự động xác định giá trị của thuộc tính chiều dài. Ví dụ, ở trên chúng ta đã tạo một mảng arr với một phần tử duy nhất. Sau đó, nó gán giá trị cho các phần tử của nó tại các chỉ mục 1, 2 và 3. Kết quả của các thao tác này là giá trị thuộc tính độ dài của mảng thay đổi thành 4.

Bạn nên phân biệt rõ ràng các chỉ mục trong một mảng với tên thuộc tính đối tượng. Tất cả các chỉ mục đều là tên thuộc tính, nhưng chỉ những thuộc tính có tên được biểu thị bằng số nguyên mới là chỉ mục. Tất cả các mảng đều là đối tượng và bạn có thể thêm thuộc tính cho chúng bằng bất kỳ tên nào. Tuy nhiên, nếu bạn chạm vào các thuộc tính là chỉ mục mảng, mảng sẽ phản hồi bằng cách cập nhật giá trị của thuộc tính độ dài nếu cần.

Xin lưu ý rằng số âm và số không nguyên có thể được sử dụng làm chỉ số mảng. Trong trường hợp này, các số được chuyển đổi thành chuỗi, được sử dụng làm tên thuộc tính.

Thêm và xóa các phần tử mảng

Chúng ta đã thấy rằng cách dễ nhất để thêm các phần tử vào một mảng là gán giá trị cho các chỉ mục mới. Bạn cũng có thể sử dụng phương thức này để thêm một hoặc nhiều phần tử vào cuối mảng. xô():

Var mảng = ; // Tạo một mảng trống arr.push("zero"); // Thêm một giá trị vào cuối arr.push("one",2); // Thêm hai giá trị nữa

Bạn cũng có thể thêm phần tử vào cuối mảng bằng cách gán giá trị cho phần tử mảng. Để chèn một phần tử vào đầu mảng, bạn có thể sử dụng phương thức unshift(), di chuyển các phần tử hiện có trong mảng đến các vị trí có chỉ số cao hơn.

Bạn có thể xóa các phần tử mảng bằng toán tử xóa, giống như các thuộc tính đối tượng thông thường:

Var mảng = ; xóa mảng; 2 trong mảng; // sai, chỉ số 2 trong mảng không được xác định arr.length; // 3: toán tử xóa không thay đổi thuộc tính độ dài của mảng

Việc xóa một phần tử cũng tương tự (nhưng hơi khác một chút) với việc gán giá trị không xác định cho phần tử đó. Lưu ý rằng việc áp dụng toán tử xóa cho một phần tử mảng không làm thay đổi giá trị của thuộc tính độ dài hoặc dịch chuyển các phần tử có chỉ mục cao hơn xuống để lấp đầy khoảng trống còn lại bằng cách xóa phần tử.

Cũng có thể loại bỏ các phần tử ở cuối mảng bằng cách gán một giá trị mới cho thuộc tính length. Mảng có một phương thức nhạc pop()(ngược lại với phương thức push()), làm giảm độ dài của mảng đi 1 và trả về giá trị của phần tử bị loại bỏ. Ngoài ra còn có một phương pháp sự thay đổi()(ngược lại với unshift()), loại bỏ phần tử ở đầu mảng. Không giống như toán tử xóa, phương thức shift() dịch chuyển tất cả các phần tử xuống vị trí bên dưới chỉ mục hiện tại của chúng.

Cuối cùng cũng có một phương pháp đa mục đích mối nối(), cho phép bạn chèn, xóa và thay thế các phần tử mảng. Nó thay đổi giá trị của thuộc tính length và chuyển các phần tử mảng sang chỉ mục thấp hơn hoặc cao hơn nếu cần. Chúng ta sẽ xem xét tất cả các phương pháp này sau.

Mảng đa chiều

JavaScript không hỗ trợ mảng đa chiều "đúng", nhưng nó cung cấp một cách tốt để mô phỏng chúng bằng cách sử dụng mảng mảng. Để truy cập một phần tử dữ liệu trong một mảng mảng, chỉ cần sử dụng toán tử hai lần.

Ví dụ: giả sử ma trận biến là một mảng gồm nhiều mảng số. Mỗi phần tử của ma trận[x] là một mảng số. Để truy cập một số cụ thể trong một mảng, bạn có thể sử dụng biểu thức ma trận[x][y]. Dưới đây là một ví dụ cụ thể trong đó mảng hai chiều được sử dụng làm bảng nhân:

// Tạo mảng nhiều chiều var table = new Array(10); // Có 10 hàng trong bảng for(var i = 0; i

Các phương thức của lớp Array

Tiêu chuẩn ECMAScript 3 định nghĩa Array.prototype là một tập hợp các hàm thuận tiện để làm việc với mảng, có sẵn dưới dạng phương thức trên bất kỳ mảng nào. Những phương pháp này sẽ được trình bày ở các phần dưới đây.

phương thức tham gia ()

Phương thức Array.join() chuyển đổi tất cả các phần tử mảng thành chuỗi, nối chúng và trả về chuỗi kết quả. Là một đối số tùy chọn, bạn có thể truyền một chuỗi cho phương thức sẽ được sử dụng để phân tách các phần tử trong chuỗi kết quả. Nếu chuỗi phân cách không được chỉ định thì dấu phẩy sẽ được sử dụng. Ví dụ: đoạn sau dẫn đến chuỗi "1,2,3":

Var mảng = ; mảng.join(); // "1,2,3" arr.join("-"); // "1-2-3"

phương thức đảo ngược()

Phương thức Array.reverse() đảo ngược thứ tự các phần tử trong một mảng và trả về một mảng được sắp xếp lại. Hoán vị được thực hiện trực tiếp trong mảng ban đầu, tức là. Phương thức này không tạo một mảng mới với các phần tử được sắp xếp lại mà thay vào đó sắp xếp lại chúng trong một mảng đã tồn tại. Ví dụ: đoạn mã sau, sử dụng các phương thức Reverse() và join(), sẽ tạo ra chuỗi "3,2,1":

Var mảng = ; arr.reverse().join(); // "3,2,1"

phương thức sắp xếp()

Phương thức Array.sort() sắp xếp các phần tử trong mảng nguồn và trả về mảng đã sắp xếp. Nếu phương thức Sort() được gọi mà không có đối số, việc sắp xếp sẽ được thực hiện theo thứ tự bảng chữ cái (các phần tử tạm thời được chuyển đổi thành chuỗi để so sánh nếu cần). Các phần tử không xác định sẽ được chuyển xuống cuối mảng.

Để sắp xếp theo thứ tự khác với thứ tự bảng chữ cái, bạn có thể chuyển hàm so sánh làm đối số cho phương thức Sort(). Hàm này thiết lập đối số nào trong hai đối số của nó sẽ đứng đầu trong danh sách được sắp xếp. Nếu đối số đầu tiên phải đứng trước đối số thứ hai thì hàm so sánh phải trả về số âm. Nếu đối số đầu tiên theo sau đối số thứ hai trong một mảng được sắp xếp thì hàm phải trả về một số lớn hơn 0. Và nếu hai giá trị tương đương nhau (nghĩa là thứ tự của chúng không quan trọng), hàm so sánh sẽ trả về 0:

Var mảng = ; mảng.sort(); // Thứ tự bảng chữ cái: 1111, 222, 33, 4 arr.sort(function(a,b) ( // Thứ tự số: 4, 33, 222, 1111 return a-b; // Trả về 0 // tùy theo thứ tự sắp xếp a và B)); // Sắp xếp theo hướng ngược lại, từ lớn nhất đến nhỏ nhất arr.sort(function(a,b) (return b-a));

Hãy lưu ý rằng việc sử dụng một hàm không tên trong đoạn mã này sẽ thuận tiện như thế nào. Chức năng so sánh chỉ được sử dụng ở đây nên không cần đặt tên cho nó.

phương thức concat()

Phương thức Array.concat() tạo và trả về một mảng mới chứa các phần tử của mảng ban đầu mà concat() được gọi và các giá trị của bất kỳ đối số nào được truyền cho concat(). Nếu bất kỳ đối số nào trong số này là một mảng thì các phần tử của nó sẽ được thêm vào mảng trả về. Tuy nhiên, cần lưu ý rằng không có phép biến đổi đệ quy một mảng các mảng thành mảng một chiều. Phương thức concat() không thay đổi mảng ban đầu. Dưới đây là một số ví dụ:

Var mảng = ; mảng.concat(4, 5); // Return arr.concat(); // Return arr.concat(,) // Return arr.concat(4, ]) // Return ]

phương thức slice()

Phương thức Array.slice() trả về một lát hoặc mảng con của mảng đã chỉ định. Hai đối số của phương thức chỉ định phần đầu và phần cuối của đoạn được trả về. Mảng trả về chứa phần tử có số được chỉ định trong đối số thứ nhất, cộng với tất cả các phần tử tiếp theo, tối đa (nhưng không bao gồm) phần tử có số được chỉ định trong đối số thứ hai.

Nếu chỉ đưa ra một đối số, mảng trả về chứa tất cả các phần tử từ vị trí bắt đầu đến cuối mảng. Nếu bất kỳ đối số nào là âm, nó sẽ xác định số phần tử tương ứng với phần cuối của mảng. Vì vậy, đối số -1 tương ứng với phần tử cuối cùng của mảng và đối số -3 tương ứng với phần tử thứ ba của mảng tính từ cuối. Dưới đây là một số ví dụ:

Var mảng = ; mảng.slice(0,3); // Return arr.slice(3); // Return arr.slice(1,-1); // Return arr.slice(-3,-2); // Trở lại

phương thức mối nối()

Phương thức Array.splice() là một phương thức chung thực hiện việc chèn hoặc loại bỏ các phần tử mảng. Không giống như các phương thức slice() và concat(), phương thức splice() sửa đổi mảng ban đầu mà nó được gọi. Lưu ý rằng các phương thức splice() và slice() có tên rất giống nhau nhưng thực hiện các thao tác hoàn toàn khác nhau.

Phương thức splice() có thể loại bỏ các phần tử khỏi một mảng, chèn các phần tử mới hoặc thực hiện cả hai cùng một lúc. Các phần tử mảng được dịch chuyển khi cần thiết để tạo ra một chuỗi liên tục sau khi chèn hoặc xóa.

Đối số đầu tiên của phương thức splice() chỉ định vị trí trong mảng mà việc chèn và/hoặc xóa sẽ được thực hiện. Đối số thứ hai chỉ định số phần tử cần xóa (cắt) khỏi mảng. Nếu đối số thứ hai bị bỏ qua, tất cả các phần tử mảng từ phần được chỉ định đến cuối mảng sẽ bị xóa. Phương thức splice() trả về một mảng gồm các phần tử đã bị loại bỏ hoặc (nếu không có phần tử nào bị xóa) một mảng trống.

Hai đối số đầu tiên của phương thức splice() chỉ định các phần tử mảng cần loại bỏ. Theo sau các đối số này có thể là bất kỳ số lượng đối số bổ sung nào chỉ định các phần tử sẽ được chèn vào mảng, bắt đầu từ vị trí được chỉ định trong đối số đầu tiên.

Var mảng = ; mảng.splice(4); // Return , arr = arr.splice(1,2); // Return , arr = arr.splice(1,1); // Trở lại ; mảng = mảng = ; arr.splice(2,0,"a","b"); // Trở lại ; mảng =

Phương thức push() và pop()

Các phương thức push() và pop() cho phép bạn làm việc với các mảng như thể chúng là các ngăn xếp. Phương thức push() thêm một hoặc nhiều phần tử mới vào cuối mảng và trả về độ dài mới của mảng. Phương thức pop() thực hiện thao tác ngược lại - nó loại bỏ phần tử cuối cùng của mảng, giảm độ dài của mảng và trả về giá trị mà nó đã loại bỏ. Lưu ý rằng cả hai phương pháp này đều sửa đổi mảng ban đầu thay vì tạo bản sao đã sửa đổi của mảng đó.

phương thức unshift() và shift()

Các phương thức unshift() và shift() hoạt động gần giống như push() và pop(), ngoại trừ việc chúng chèn và xóa các phần tử ở đầu mảng thay vì ở cuối mảng. Phương thức unshift() chuyển các phần tử hiện có sang các chỉ mục lớn hơn để giải phóng không gian, thêm phần tử hoặc các phần tử vào đầu mảng và trả về độ dài mới của mảng. Phương thức shift() loại bỏ và trả về phần tử đầu tiên của mảng, dịch chuyển tất cả các phần tử tiếp theo xuống một vị trí để chiếm khoảng trống ở đầu mảng.

JavaScript được thiết kế dựa trên một mô hình đơn giản. Khái niệm này dựa trên các đối tượng đơn giản. Một đối tượng là một tập hợp các thuộc tính và mỗi thuộc tính bao gồm một tên và một giá trị được liên kết với tên đó. Giá trị thuộc tính có thể là một hàm, có thể được gọi là phương pháp sự vật. Ngoài các đối tượng có sẵn của trình duyệt, bạn có thể xác định các đối tượng của riêng mình. Chương này mô tả cách sử dụng các đối tượng, thuộc tính, hàm và phương thức cũng như cách tạo các đối tượng của riêng bạn.

Tổng quan về đối tượng

Các đối tượng trong JavaScript, cũng như trong nhiều ngôn ngữ lập trình khác, tương tự như các đối tượng trong đời thực. Khái niệm về các đối tượng JavaScript dễ hiểu hơn bằng cách vẽ ra sự tương đồng với các đối tượng trong đời thực.

Trong JavaScript, một đối tượng là một đơn vị độc lập có các thuộc tính và loại cụ thể. Hãy so sánh, ví dụ, với một cái cốc. Một chiếc cốc có màu sắc, hình dạng, trọng lượng, chất liệu làm nên nó, v.v. Tương tự, các đối tượng JavaScript có các thuộc tính xác định đặc điểm của chúng.

Đối tượng và thuộc tính

Trong JavaScript, một đối tượng có các thuộc tính liên kết với nó. Một thuộc tính đối tượng có thể được hiểu là một biến được gán cho một đối tượng. Thuộc tính đối tượng về cơ bản giống như các biến JavaScript, ngoại trừ việc chúng được gán cho đối tượng. Các thuộc tính của một đối tượng xác định các đặc điểm của nó. Bạn có thể truy cập thuộc tính của một đối tượng bằng ký hiệu dấu chấm:

Tên đối tượng.propertyName

Giống như tất cả các biến JavaScript, tên đối tượng (cũng có thể là biến) và tên thuộc tính có phân biệt chữ hoa chữ thường. Bạn có thể xác định một thuộc tính bằng cách chỉ định giá trị của nó. Ví dụ: hãy tạo một đối tượng myCar và xác định các thuộc tính make , model và Year của nó như sau:

Var myCar = new Object(); myCar.make = "Ford"; myCar.model = "Mustang"; myCar.year = 1969;

Thuộc tính đối tượng không xác định là không xác định (không phải null).

Ôtô của tôi. màu sắc;

Các thuộc tính của đối tượng JavaScript cũng có thể được truy cập hoặc đặt bằng ký hiệu ngoặc (xem để biết thêm chi tiết). Các đối tượng đôi khi được gọi mảng kết hợp, vì mỗi thuộc tính được liên kết với một giá trị chuỗi có thể được sử dụng để truy cập nó. Vì vậy, ví dụ: bạn có thể truy cập các thuộc tính của đối tượng myCar như sau:

MyCar["make"] = "Ford"; myCar["model"] = "Mustang"; myCar["năm"] = 1969;

Tên thuộc tính đối tượng có thể là chuỗi JavaScript hoặc bất kỳ thứ gì có thể được chuyển đổi thành chuỗi, bao gồm cả chuỗi trống. Tuy nhiên, bất kỳ tên thuộc tính nào chứa mã định danh JavaScript không hợp lệ (ví dụ: tên thuộc tính chứa dấu cách và dấu gạch ngang hoặc bắt đầu bằng số) đều có thể được truy cập bằng dấu ngoặc vuông. Ký hiệu này cũng hữu ích khi tên thuộc tính phải được xác định động (khi tên thuộc tính không được xác định cho đến khi chạy). Ví dụ dưới đây:

Var myObj = new Object(), str = "myString", rand = Math.random(), obj = new Object(); myObj.type = "Cú pháp dấu chấm"; myObj["ngày tạo"] = "Chuỗi có dấu cách"; myObj = "Giá trị chuỗi"; myObj = "Số ngẫu nhiên"; myObj = "Đối tượng"; myObj[""] = "Ngay cả một chuỗi trống"; console.log(myObj);

Lưu ý rằng tất cả các khóa có dấu ngoặc vuông đều được chuyển đổi thành loại Chuỗi, vì các đối tượng trong JavaScript chỉ có thể có loại Chuỗi làm khóa. Ví dụ: trong đoạn mã trên, khi khóa obj được thêm vào myObj, JavaScript sẽ gọi phương thức obj.toString() và sử dụng chuỗi kết quả đó làm khóa mới.

Bạn cũng có thể truy cập các thuộc tính bằng giá trị chuỗi được lưu trữ trong một biến:

Var propertyName = "làm"; myCar = "Ford"; propertyName = "mô hình"; myCar = "Mustang";

Bạn có thể sử dụng dấu ngoặc vuông trong mệnh đề for...in để lặp qua tất cả các thuộc tính của một đối tượng được phép. Để hiển thị cách hoạt động của tính năng này, hàm sau hiển thị tất cả thuộc tính của một đối tượng khi bạn truyền chính đối tượng đó và tên của nó làm đối số cho hàm:

Hàm showProps(obj, objName) ( var result = ""; for (var i in obj) ( if (obj.hasOwnProperty(i)) ( result += objName + "." + i + " = " + obj[i ] + "\n"; ) ) trả về kết quả;

Vì vậy, nếu chúng ta gọi hàm này như showProps(myCar, "myCar"), chúng ta sẽ nhận được kết quả:

MyCar.make = Ford myCar.model = Mustang myCar.year = 1969

Liệt kê tất cả các thuộc tính của một đối tượng

Sử dụng hàm tạo

Một cách khác để tạo một đối tượng theo hai bước được mô tả dưới đây:

  1. Xác định loại đối tượng bằng cách viết hàm xây dựng. Tên của hàm như vậy thường bắt đầu bằng chữ in hoa.
  2. Tạo một thể hiện của một đối tượng bằng từ khóa mới.

Để xác định loại đối tượng, hãy tạo một hàm xác định loại đối tượng, tên, thuộc tính và phương thức của đối tượng. Ví dụ: giả sử bạn muốn tạo một loại đối tượng để mô tả ô tô. Bạn muốn một đối tượng thuộc loại này được gọi là car và bạn muốn nó có các thuộc tính nhãn hiệu, kiểu dáng và năm. Để làm điều này, hãy viết hàm sau:

Xe chức năng( hãng, model, năm) ( this.make = make; this.model = model; this.year = năm; )

Lưu ý rằng điều này được sử dụng để gán các giá trị (được truyền dưới dạng đối số của hàm) cho các thuộc tính của đối tượng.

Bây giờ bạn có thể tạo một đối tượng có tên mycar như thế này:

Var mycar = Xe mới("Đại bàng", "Talon TSi", 1993);

Câu lệnh này tạo một đối tượng kiểu Car với tham chiếu mycar và gán các giá trị nhất định cho các thuộc tính của nó. Giá trị của mycar.make sẽ là chuỗi "Eagle", mycar.year sẽ là số nguyên 1993, v.v.

Bạn có thể tạo bao nhiêu đối tượng ô tô tùy thích bằng cách gọi new . Ví dụ:

Var kenscar = Xe mới("Nissan", "300ZX", 1992); var vpgscar = Xe mới("Mazda", "Miata", 1990);

Một đối tượng có thể có một thuộc tính sẽ là một đối tượng khác. Ví dụ: phần sau đây định nghĩa một đối tượng thuộc loại Person như sau:

Hàm Người(tên, tuổi, giới tính) ( this.name = name; this.age = age; this.sex = sex; )

và sau đó tạo hai thể hiện đối tượng Person mới như sau:

Var rand = Người mới("Rand McKinnon", 33, "M"); var ken = Người mới("Ken Jones", 39, "M");

Sau đó, bạn có thể viết lại định nghĩa về ô tô để bao gồm thuộc tính owner, được gán cho một đối tượng người như sau:

Xe chức năng(nhãn hiệu, model, năm, chủ sở hữu) ( this.make = make; this.model = model; this.year = năm; this.owner = owner; )

Sau đó, để khởi tạo các đối tượng mới, hãy làm theo các hướng dẫn sau:

Var car1 = Xe mới("Đại bàng", "Talon TSi", 1993, rand); var car2 = Xe mới("Nissan", "300ZX", 1992, ken);

Lưu ý rằng thay vì truyền một chuỗi, chữ hoặc số nguyên khi tạo đối tượng mới, các biểu thức ở trên chuyển các đối tượng rand và ken làm đối số cho hàm. Bây giờ, nếu bạn cần tìm tên chủ sở hữu của car2, bạn có thể làm như sau:

Xe2.owner

Lưu ý rằng bất kỳ lúc nào bạn cũng có thể thêm thuộc tính mới vào đối tượng đã tạo trước đó. Ví dụ, biểu thức

Car1.color = "đen";

thêm thuộc tính màu vào car1 và đặt giá trị của nó thành "đen". Tuy nhiên, điều này không ảnh hưởng đến bất kỳ đối tượng nào khác. Để thêm thuộc tính mới cho tất cả các đối tượng cùng loại, bạn phải thêm thuộc tính vào định nghĩa loại của đối tượng ô tô.

Sử dụng phương thức Object.create

Các đối tượng cũng có thể được tạo bằng phương thức Object.create. Phương pháp này rất thuận tiện vì nó cho phép bạn chỉ định một đối tượng nguyên mẫu cho một đối tượng mới của bạn mà không cần xác định hàm tạo.

// danh sách các thuộc tính và phương thức cho Animal var Animal = ( type: "Invertebrates", // Giá trị mặc định của loại displayType: function() ( // Phương thức hiển thị loại của đối tượng Animal console.log(this.type); ) ); // Tạo một đối tượng Động vật var Animal1 = Object.create(Animal); Animal1.displayType(); // Kết quả: Động vật không xương sống // Tạo một đối tượng Động vật và gán cho nó type = Fishes var Fish = Object.create(Animal); cá.type = "Cá"; cá.displayType(); // Kết quả đầu ra:Cá

Di sản

Tất cả các đối tượng trong JavaScript đều kế thừa từ ít nhất một đối tượng khác. Đối tượng mà sự kế thừa xảy ra được gọi là nguyên mẫu và các thuộc tính được kế thừa có thể được tìm thấy trong đối tượng nguyên mẫu của hàm tạo.

Chỉ mục thuộc tính đối tượng

Trong JavaScript 1.0, bạn có thể tham chiếu đến các thuộc tính của một đối tượng bằng tên hoặc theo chỉ mục thứ tự của nó. Trong JavaScript 1.1 trở lên, nếu ban đầu bạn xác định một thuộc tính theo tên thì bạn phải luôn tham chiếu đến thuộc tính đó theo tên của nó và nếu ban đầu bạn xác định một thuộc tính theo chỉ mục thì bạn phải tham chiếu đến thuộc tính đó theo chỉ mục của nó.

Giới hạn này được áp dụng khi bạn tạo một đối tượng và các thuộc tính của nó bằng cách sử dụng hàm khởi tạo (như chúng ta đã làm trước đó với kiểu Xe hơi) và khi bạn xác định rõ ràng các thuộc tính riêng lẻ (ví dụ: myCar.color="red"). Nếu ban đầu bạn xác định một thuộc tính đối tượng thông qua một chỉ mục, ví dụ myCar = "25 mpg" , thì sau đó bạn chỉ có thể tham chiếu đến thuộc tính này là myCar .

Ngoại lệ đối với quy tắc là các đối tượng được hiển thị từ HTML, chẳng hạn như mảng biểu mẫu. Bạn luôn có thể tham chiếu đến các đối tượng trong các mảng này theo chỉ mục của chúng (dựa trên thứ tự chúng xuất hiện trong tài liệu HTML) hoặc theo tên của chúng (nếu chúng đã được xác định). Ví dụ: nếu thẻ html thứ hai

trong tài liệu có giá trị thuộc tính NAME là "myForm", bạn có thể tham chiếu biểu mẫu đó như sau: document.forms hoặc document.forms["myForm"] hoặc document.myForm .

Xác định thuộc tính cho một loại đối tượng

Bạn có thể thêm thuộc tính vào loại đối tượng được xác định trước đó bằng thuộc tính đặc biệt nguyên mẫu. Thông qua nguyên mẫu, một thuộc tính được tạo ra chung cho tất cả các đối tượng thuộc một loại nhất định chứ không chỉ một phiên bản của loại đối tượng này. Đoạn mã sau chứng minh điều này bằng cách thêm thuộc tính màu cho tất cả các đối tượng thuộc loại ô tô và sau đó gán giá trị cho thuộc tính màu của đối tượng car1.

Car.prototype.color = null; car1.color = "đen";

Mã bên dưới cho thấy cách bạn có thể sử dụng getter và setter để mở rộng nguyên mẫu của đối tượng Date và thêm thuộc tính năm vào đó. Thuộc tính này sẽ hoạt động với tất cả các phiên bản của lớp Date. Mã này sử dụng các phương thức lớp Date hiện có getFullYear và setFullYear để vận hành getter và setter.

Xác định getter và setter cho thuộc tính năm:

Var d = Date.prototype; Object.defineProperty(d, "year", ( get: function() ( return this.getFullYear(); ), set: function(y) ( this.setFullYear(y); ) ));

Sử dụng thuộc tính năm được chỉ định bởi getter và setter:

Var bây giờ = Ngày mới(); console.log(now.year); // 2000 now.year = 2001; // 987617605170 console.log(bây giờ); // Thứ Tư ngày 18 tháng 4 11:13:25 GMT-0700 (Giờ ban ngày Thái Bình Dương) 2001

Về cơ bản, getters và setters có thể là:

Khi xác định một getter và setter bằng cách sử dụng , tất cả những gì bạn cần làm là đặt tiền tố getter bằng get và setter với set . Trong trường hợp này, phương thức getter không nên mong đợi bất kỳ tham số nào, trong khi phương thức setter lấy một tham số duy nhất (giá trị mới để gán cho thuộc tính). Ví dụ:

Var o = ( a: 7, get b() ( return this.a + 1; ), set c(x) ( this.a = x / 2; ) );

Getters và setters có thể được thêm vào một đối tượng hiện có bất kỳ lúc nào bằng cách sử dụng phương thức Object.defineProperties. Tham số đầu tiên của phương thức này là đối tượng mà bạn muốn gán getter và setter. Tham số thứ hai là một đối tượng có tên thuộc tính sẽ tương ứng với tên của thuộc tính được tạo và các giá trị là các đối tượng xác định getter và setter của thuộc tính được tạo. Ví dụ sau tạo chính xác getter và setter giống như ví dụ trên:

Var o = ( a: 0 ); Object.defineProperties(o, ( "b": ( get: function() ( return this.a + 1; ) ), "c": ( set: function(x) ( this.a = x / 2; ) ) )); oc = 10; // Chạy một setter gán 10/2 (5) cho thuộc tính "a" console.log(o.b); // Kích hoạt một getter trả về a + 1 (tức là 6)

Bạn sử dụng biểu mẫu nào trong hai biểu mẫu để xác định thuộc tính tùy thuộc vào phong cách lập trình và nhiệm vụ hiện tại của bạn. Nếu bạn đang sử dụng trình khởi tạo đối tượng để xác định nguyên mẫu, có thể bạn sẽ sử dụng biểu mẫu đầu tiên trong hầu hết các trường hợp. Nó nhỏ gọn và tự nhiên hơn. Tuy nhiên, không có gì lạ khi dạng thứ hai là dạng duy nhất khả thi trong trường hợp bạn đang làm việc với một đối tượng hiện có mà không truy cập được định nghĩa của nó. Dạng thứ hai phản ánh tốt nhất tính chất động của JavaScript - nhưng có thể làm cho mã khó đọc và khó hiểu.

Xóa thuộc tính

Bạn có thể xóa một thuộc tính bằng toán tử xóa. Đoạn mã sau đây cho biết cách xóa một thuộc tính.

// Tạo một đối tượng mới, myobj, với hai thuộc tính a và b. var myobj = Đối tượng mới; myobj.a = 5; myobj.b = 12; // Loại bỏ thuộc tính a, để lại myobj chỉ còn thuộc tính b. xóa myobj.a;

Bạn cũng có thể sử dụng delete để xóa biến toàn cục nếu từ khóa var không được sử dụng khi khai báo nó:

G = 17; xóa g;

  • Để có một nghiên cứu chi tiết, hãy đọc.
  • Để tìm hiểu về các lớp ECMAScript 2015 (cách mới để xác định đối tượng), hãy đọc chương này.

Mảng là một trong những loại biến được sử dụng phổ biến nhất cho phép bạn lưu trữ nhiều giá trị tuần tự ở “một nơi”. Tuy nhiên, khi nói đến JavaScript, vẫn còn chỗ để cải thiện.

Trong bài viết này, chúng ta sẽ xem xét ba kỹ thuật ít được biết đến có thể được sử dụng khi làm việc với mảng.

1. Thêm thuộc tính tùy chỉnh vào mảng

Nếu bạn sử dụng tìm kiếm để tìm định nghĩa của một mảng trong ngôn ngữ JavaScript, hầu hết các nguồn sẽ cho biết rằng loại giá trị biến này được biểu diễn dưới dạng một đối tượng.

Nói chung, rất nhiều thứ chúng ta gặp trong JavaScript là các đối tượng. Công bằng mà nói thì ngôn ngữ này cũng chứa các kiểu dữ liệu “nguyên thủy”, nhưng giá trị của chúng bằng cách nào đó được sử dụng trong các thuộc tính bên trong các đối tượng.

2. Truy cập các phần tử mảng trong vòng lặp

Vì chỉ số mảng chỉ có thể nhận giá trị dương nên việc đếm bắt đầu từ 0. Sau này chúng ta có thể sử dụng chỉ mục này để truy cập phần tử mảng tại một vòng lặp nhất định.

ECMAScript6 đã giới thiệu một cách để cuộn qua một mảng mà không sử dụng chỉ mục mà thông qua một vòng lặp for…of mới.

Vòng lặp for...of được thiết kế để lặp qua các phần tử của một mảng mà không ảnh hưởng đến chỉ mục của phần tử đó.

Var ary = ["cam","táo","vải thiều"]; for (let item of ary)( console.log(item); ) // "orange", "apple", "lychee" Để so sánh: xuất các chỉ số mục trong vòng lặp for. var ary = ["cam","táo","vải thiều"]; cho (var item = 0; mục< ary.length; item++){ console.log(item); } // 0, 1, 2

3. Số phần tử không phải là thứ nguyên của mảng

Khi nói về kích thước của một mảng, chúng ta thường nghĩ nó là số phần tử được lưu trữ trong đó. Trên thực tế, điều này không hoàn toàn đúng - thuộc tính độ dài được tính tùy thuộc vào chỉ số tối đa của phần tử.

Thuộc tính độ dài rất mơ hồ. Để xác minh điều này, chỉ cần nhìn vào các thao tác sau:

Khác nhau = ; ary.length = 3; console.log(ary.length); // 3 ary = "abcd"; console.log(ary.length); // 6

Trong ví dụ trước, chỉ cần đặt phần tử ở vị trí thứ năm là đủ, do đó độ dài của mảng trở thành 6. Nếu bạn nghĩ rằng các chỉ mục từ 0 đến 4 sẽ được tạo tự động thì bạn đã nhầm. Điều này có thể được kiểm tra bằng cách sử dụng toán tử in.

Khác nhau = ; ary.length = 3; console.log(ary.length); // 3 ary = "abcd"; console.log(ary.length); // 6 console.log(0 in ary); // SAI

Trong trường hợp này, sẽ công bằng nếu gọi mảng ary là "thưa thớt".

Chúng ta cũng có thể thao tác thuộc tính length để cắt bớt mảng. Ví dụ dưới đây minh họa việc “mất” phần tử ở chỉ số 5 bằng cách giảm thuộc tính độ dài của mảng ary.

Khác nhau = ; ary.length = 3; console.log(ary.length); // 3 ary = "abcd"; console.log(ary.length); // 6 ary.length = 2; console.log(ary.length); // 2 console.log(ary); // không xác định

Khi nghiên cứu các đối tượng JavaScript, tất cả chúng ta đều gặp những cụm từ như “ Mảng là những đối tượng đơn giản trong Javascript" Hôm nay tôi muốn khám phá thêm tuyên bố này:

Xem ví dụ

Nếu bạn nhìn vào ví dụ trên, rõ ràng mảng là một kiểu đối tượng. Nhưng nó có nghĩa gì?

Nếu bạn không quen với toán tử typeof, bạn có thể tìm hiểu thêm về nó ở đây.

Di sản

Để hiểu sự khác biệt giữa JavaScript làm việc với đối tượng và mảng, hãy xem nguyên tắc kế thừa.

Mỗi đối tượng chứa một tham chiếu đến đối tượng cha (nguyên mẫu) của nó. Khi bạn gọi một phương thức, JavaScript sẽ tìm kiếm nó trong đối tượng bạn đang làm việc. Nếu không tìm thấy phương thức, việc tìm kiếm nguyên mẫu sẽ bắt đầu. Việc tìm kiếm được thực hiện dọc theo toàn bộ chuỗi nguyên mẫu cho đến khi tìm thấy một phương thức hoặc đạt được đối tượng gốc.

Xem ví dụ

Ví dụ trên tạo một đối tượng người với tham số tên riêng của nó. Khi phương thức toString được gọi, đối tượng người đầu tiên được kiểm tra, sau đó là kiểm tra nguyên mẫu của nó ( Object.prototype). Sử dụng logic nguyên mẫu, thường trả về .

Sự khác biệt giữa các đối tượng và mảng

Mảng có sự khác biệt đáng kể so với các đối tượng JavaScript truyền thống. Lý do nằm ở đối tượng Array.prototype, nó đại diện cho tất cả các phương thức vốn có trong mảng. Mỗi mảng mới đều kế thừa các phương thức này từ Array.prototype.

Điều quan trọng cần lưu ý là giá trị của thuộc tính nguyên mẫu trong Array.prototype là Object.prototype . Điều này có nghĩa là mảng chỉ là đối tượng nhưng có thêm các phương thức bổ sung. Không có gì một đối tượng có thể làm mà một mảng không thể làm được.

Xem ví dụ

Điều kỳ lạ

Giống như các đối tượng JavaScript, mảng có những đặc điểm riêng.

Thuộc tính không được lập chỉ mục

Vì mảng chỉ là đối tượng nên bạn có thể áp dụng các thuộc tính không được lập chỉ mục cho chúng. Đây thường là điều đầu tiên gây ngạc nhiên. Trong ví dụ bên dưới, tôi đang đặt hai thuộc tính không được lập chỉ mục được gọi là được sắp xếp và được tác giả bởi mảng tạp hóa.

Lưu ý: Giống như đối tượng, cả dấu chấm và dấu ngoặc đơn đều được hỗ trợ.

Xem ví dụ

chiều dài

Thuộc tính độ dài của một mảng cũng thường gây nhầm lẫn. Thuộc tính này thường bị nhầm lẫn với việc đếm các phần tử trong mảng. Tuy nhiên, độ dài lớn hơn về số lượng so với chỉ số mảng lớn nhất. Do đó, các thuộc tính không được lập chỉ mục không ảnh hưởng đến độ dài của mảng, như trong ví dụ.

Một tình huống khác trong đó độ dài có thể gây hiểu nhầm là nếu chúng ta đang cố gắng thêm một phần tử có chỉ số lớn hơn giá trị mảng độ dài hiện tại. Lưu ý rằng trong ví dụ, độ dài của mảng tăng từ 2 lên 10 ngay sau khi thêm phần tử thứ ba vào mảng ở chỉ số 9.

Khi giá trị của thuộc tính độ dài thay đổi, mọi phần tử có chỉ mục trên giá trị độ dài mới sẽ bị xóa.

Ghi chú:

Để có được giá trị độ dài chính xác, bạn có thể sử dụng Object.keys(groceries).length . Lưu ý rằng điều này cũng bao gồm các thuộc tính không được lập chỉ mục cho đến khi bạn xác định chúng là không thể đếm được. Đó là:

Object.defineProperty(cửa hàng tạp hóa, "được sắp xếp", ( value: false, enumerable: false, configable: true, writable: true ));

Vậy chúng ta nên làm gì?

Nếu bạn cần tạo một tập hợp các thuộc tính thuộc nhiều loại khác nhau, hãy sử dụng tính năng tạo đối tượng JavaScript. Trong tất cả các trường hợp khác, bạn có thể sử dụng mảng.

Bản dịch của bài viết “JavaScript: Arrays vs Objects” được nhóm dự án thân thiện chuẩn bị.