Array-like object thực chất là gì?

Em có search trên mạng và đọc qua ở một số link:

nhưng vân thấy mơ hồ về “array-like” , thực chất nó là gì ? tại sao người ta lại phát sinh ra thêm khái niệm này cung như dùng nó vào mục đích gì ạ.

Mọi nhười có thể giúp e trả lời các câu hỏi trên với được không ạ.
Em xin cảm ơn anh/chị ?

thì đơn giản là Array trong javascript nó là một loại object thôi, người ta dùng nó như object thì có gì lạ?

3 Likes

Ở trong Javascript, mọi thứ là object, và thực sự bạn truy cập member của nó kiểu gì cũng được, miễn là nó tồn tại và có chức năng như mình muốn.

Nếu nó trông giống vịt,
bơi như vịt,
và quàng quạc như vịt,
thì nó có thể chính là một con vịt.

Trong JS có class Array, cái quan trọng ở đây là nó có các property và method cho các chức năng xử lý mảng, giờ nếu làm một cái object khác cũng có toàn bộ hoặc 1 phần các property và method giống với Array thì bạn hoàn toàn có thể dùng object này với các đoạn code expect đầu vào là array, bởi vì chức năng quan trọng hơn (chỉ cần xài nó như array là được, không quan trọng nó là cái gì).

7 Likes

Trong JS, Array là một object, nhưng nó là object đặc biệt. Nếu gọi tên chính xác thì gọi là native array.

Đối với các object thông thường, phần code cho object hoàn toàn 100% là JavaScript. Tuy nhiên, đối với native array, implementation của nó đa số là C++ (hoặc Rust), và cung cấp interface (API) dưới dạng JavaScript.

Do đó, nếu có ai đó cố viết array bằng JS tất cả thì array đó chỉ là array-like object, không phải là native array, và tốc độ thực thi cũng không thể bằng so với native array, vì C++ nhanh hơn JS.

7 Likes

Cám ơn mọi người đa vào comment giúp đơ e ạ. Trong các ý kiến của a/c e thấy comment của anh @hungaya đọc dễ hiểu hơn chút nên em muốn comment hỏi lại anh một số ý ạ. Anh nói:

Vậy thì e có ví dụ đơn giản này :myArr = [1,2,3]
=> thì cái này KHÔNG phải là native array mà chỉ là array-like object thôi phải không ạ.
Vậy là trước giờ code JS khai báo kiểu vậy thực chất là mình toàn dùng array-like object thôi à ?

Mà e cung đang không hiểu câu "cố viết array bằng JS" của anh là như nào ?
Vì trong câu hỏi của em đang muốn đề cập đến khái niệm Array trong JS ( e có để tag JavaScript cho bài post) thì mình đương nhiên phải viết bằng code JS chứ không lẽ lại viết bằng ngôn ngữ khác ?

Mong anh phân tích thêm giúp e. Tks anh nhiều ạ

Mình có test thử trên console của trình duyệt và thấy như thế này:

image

[1, 2, 3] thì vẫn là kiểu Array.

5 Likes

[1,2,3] vẫn là native array bạn à
Array like obj là kiểu này nè


Thực tế trong khi code bạn cũng ko cần phải tự code array-like obj đâu mà lo.
Còn muốn hiểu sâu thì bạn đọc về Javascript Engine, prototype nha,

5 Likes

myArr là native array rồi, khi bạn sử dụng cú pháp như vậy là đã sử dụng native array.

var myArr = [1, 2, 3];

Phân tích chi tiết hơn tí xíu, câu lệnh có thể phân thành 2 phần.

Phần 1:

[1,2,3]

Cú pháp có [ và ] thực chất hỗ trợ thay cho cú pháp khởi tạo bằng constructor thông thường.

new Array(1, 2, 3)

JS chuyển lệnh new cho C++ thực thi, C++ dựa trên các tham số do JS truyển vào (3 giá trị 1, 2, 3). Do tham số là 3 số nguyên, nên C++ tạo kiểu dữ liệu native tối ưu là Int8Array (là subclass của TypedArray), và chuyển địa chỉ (pointer) từ C++ sang JavaScript.

Mở rộng thêm, Array phía JS được hỗ trợ bởi rất nhiều class bên C++, tuỳ vào Compiler hiện thực thế nào. Nếu mảng không liên tục ([0,,,,1,,,2,,3]) thì có thể sử dụng binary tree, nếu mảng liên tục thì có thể sử dụng C array (int[], char[]). Nếu các phần tử của mảng cũng 1 kiểu dữ liệu thì có thể dùng class TypedArray (và các subclasses) hoặc TypedTree (và các subclasses).

Phần 2:

var myArr = <<pointer>>;

<<pointer>> từ C++ chuyển sang được lưu vào biến myArr.


Viết array giả bằng JS, hay array-like object là viết giống như thế này nè :penguin:

var fakeArray = {
  '0': 1,
  '1': 2,
  '2': 3,
  length: 3,

  push: function (v) {
    this[this.length] = v;
    this.length++;
  },
 
  pop: function () {
    this.length--;
    var v = this[this.length];
    delete this[this.length];
    return v;
  }
};

Muốn chuyển thành array xịn, hay native array:

var realArray = Array.from(fakeArray);
7 Likes

Ôi , sao JS nó khó hiểu vậy mn :persevere:

myArr = [ 1,2,3]

myArr là một Array mà trong JS, ArrayObject => nên myArr cung được coi là Object luôn.

Còn

var fakeArray = {
  '0': 1,
  '1': 2,
  '2': 3,
  length: 3,

  push: function (v) {
    this[this.length] = v;
    this.length++;
  },
 
  pop: function () {
    this.length--;
    var v = this[this.length];
    delete this[this.length];
    return v;
  }
};

Nhìn ro là một Object nhưng thực ra nó cung được coi là 1 Array và cụ thể nó được gọi là : array-like object

Tóm lại ArrayObjectObject cung có thể là một Array được .
Em hiểu thế đúng ko ạ ?

Arraylike object là một object có một thuộc tính là lengh. chỉ cần như vậy thôi { length: 0 } Còn nữa là nó không có Prototype Methods của một Array https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype . Array-like còn có thể truy cập được phần tử thông qua index như Set và Map, vậy Set và Map cũng là array-like.

6 Likes

Everything in JS is object nên câu này cuối cùng có ý nghĩa gì vậy @@

3 Likes

Array chỉ là 1 cái tên mà người ta đặt cho cái object. Người ta có thể đặt nó là XXX cũng không thành vấn đề, miễn sao người dùng nó biết XXX có length, có index là number, có thể duyệt for of, có thể dùng …, có thể concat tới xxx khác bla bla. lúc đó trong document của JS sẽ có XXX.prototype.map, XXX.prototype.filter… bla bla bla các thứ

bạn muốn gọi object của bạn là gì mà chả được, sao cứ phải xoắn sâu vào cái tên gọi làm chi cho mệt vậy?

5 Likes

Bạn vào đọc reference về array trong mdn sẽ thấy array có những methods và properties đặc trưng như length, map, concat,… Array-like object thì có thể sẽ có những đặc trưng này, ví dụ HTMLCollection là một kiểu array-like object, bạn cũng có thể gọi phần tử con của nó bằng method item(), giống với [ ] của array, hoặc có thể loop bằng method forEach(). Đại khái array-like object có những đặc trưng giống array nhưng ko phải array (vì một lí do nào đó mà người ta không thể dùng array). Còn một object bình thường thì nó không chắc chắn có những đặc trung như array
https://developer.mozilla.org/vi/docs/Web/JavaScript/Reference/Global_Objects/Array
https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection

3 Likes

xin lôi mọi người, do e chậm hiểu lắm nên môi lần gặp vấn đề gì là e hay phải hỏi nhiều hỏi ky chút ạ

Cám ơn mn nhiều ạ :slight_smile:

1 Like

Tks anh nhiều ạ. Sao lúc đầu mn không giải thích luôn vầy giúp e có phải vừa ngắn gọn lại dê hiểu hơn không hà .

Đơn giản vì cách giải thích như trên được chỉ ra khi bạn search Google, và nó khiến cho bạn dính 1 cái bẫy về polyfill.

Polyfill là kĩ thuật để implement các method không có trong JS standard nhưng được cộng đồng đưa ra dưới dạng proposal. Khi các proposal chưa được đưa vào ECMA thì community sẽ viết thêm các method, có khi là đổi luôn cấu trúc dữ liệu bên trong.

Ví dụ Array là mutable object, nhưng giờ yêu cầu phải chuyển tất cả các method sang dạng immutable. Cách giải quyết là viết 1 array-like object mới, dựa trên API của Array trong ECMAScript. Immutable Array có length, có index, có thừa kế Array.prototype, implement tất cả các method có trong ECMAScript’s Array, hơn nữa còn override cả tính chất enumerable, iterable, instanceof operator. Lúc này cái array-like object bạn viết ra nó không khác gì cái Array trong JS Standard, dùng API để nhận biết cũng bó tay. :v

Do đó, để cho chuẩn, bạn cần biết Array trong JS Standard hiện thực thế nào, còn các object khác do community viết nhưng mô phỏng lại các method, các thừa kế,… của Array thì là array-like object.

4 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?