2012-02-10 29 views
5

Tôi đã tạo một ứng dụng JavaScript có nhiều thao tác mảng (sắp xếp, lọc, v.v.).Tôi có thể tạo đối tượng mảng của riêng mình trong JavaScript không?

Hiện nay chức năng của tôi là như thế này:

function (myArray, arg1, arg2,...) 

nơi myArray là mảng tôi đang làm việc trên, và arg1, arg2, ... là các đối số được sử dụng bởi các chức năng để sửa đổi mảng.

Tôi nghĩ rằng nó sẽ là gọn gàng để có một sự tách biệt rõ ràng giữa các đối tượng và các đối số (a la jQuery):

myArray.function(arg1, arg2,...) 

tôi biết rằng tôi có thể sử dụng Array.prototype để thêm chức năng của tôi để tất cả các mảng, nhưng điều này có vẻ quá nặng vì các hàm tôi thêm vào thực sự đặc trưng cho trường hợp của tôi và không có ý nghĩa đối với các mảng nói chung. Tôi cũng biết rằng tôi có thể tạo một đối tượng, nhưng sau đó tôi sẽ không được hưởng lợi từ các phương thức mảng có sẵn trong JavaScript (indexOf, bộ lọc, v.v.).

Có cách nào tôi có thể tạo đối tượng mảng của riêng mình, có kế thừa các phương thức mảng mặc định và cho phép tôi thêm phương thức của riêng mình không?

+3

tiếp tục sử dụng các chức năng, bạn không cần mọi thứ trong oop – dynamic

+0

Phải, nhưng tôi thích cách làm sạch, ví dụ như để chuỗi hoặc xác định các tùy chọn/đối số mặc định. – Christophe

Trả lời

8

Bạn đã có hai lựa chọn:

Tùy chọn một là mở rộng đối tượng Array bằng cách thêm các phương thức mới vào:

Array.prototype.myMethod = function(arg1, arg2) 
{ 
    // Use 'this' to access the array. 
} 

Lợi thế là mọi mảng javascript giờ đây sẽ có phương thức bổ sung này. Điều này cũng có thể là một bất lợi khi nhiều thư viện javascript (bên ngoài) cố gắng thêm các phương thức tương tự. Hơn nữa, phương pháp mới này sẽ xuất hiện trong các cấu trúc for(var item in myArray) có thể có vấn đề.

Lựa chọn hai là tạo ra một "phương pháp nhà máy" cho mảng mở rộng của bạn:

function MyExtendedArray = function() 
{ 
    var array = []; 
    array.myMethod = function(arg1, arg2) { 
     // Use 'this' or 'array' to access the array. 
    }; 

    return array; 
}; 

Bây giờ bạn có thể viết những dòng này để tạo ra một mảng mở rộng mới:

var arr = MyExtendedArray(); 
+0

Tôi nghĩ phương pháp nhà máy chính xác là những gì tôi cần cho ứng dụng cụ thể của mình. Nó rất rõ ràng ... không phải là tôi thấy nó :-) Cảm ơn! – Christophe

4

No. Array không thể được phân loại và vẫn hoạt động như một mảng. Cụ thể, thuộc tính length sẽ không thay đổi để phản ánh các yếu tố được thêm vào hoặc bị xóa khỏi mảng.

function MyArray() {} 
MyArray.prototype = []; 
MyArray.prototype.constructor = MyArray; 
var instance = new MyArray; 
instance[0] = 0; 
alert(instance.length); // alerts 0 

Lý do điều này xảy ra là bởi vì chỉ có các đối tượng được tạo ra thông qua new Array hoặc đường cú pháp như [] có xử lý đặc biệt xung quanh chiều dài.

Các new MyArray trên tạo ra một đối tượng thường xuyên có nguyên mẫu là một Array, nhưng không có gì về các nhà điều hành new đó kiểm tra xem nguyên mẫu của một đối tượng là một Array và thiết lập các length xử lý đặc biệt là.

+0

+1 thx để giải thích. – Christophe

+0

Rất kỳ lạ, nếu bạn sử dụng phương thức .push() để lưu trữ dữ liệu vào mảng, độ dài cập nhật đúng cách. –

+1

@ZlatinZlatev, các ứng viên EcmaScript gần đây có mục tiêu cho phép phân lớp các thứ như Array, RegExp và Date để câu trả lời này có thể không chính xác lâu hơn nữa. Có lẽ bạn đang thấy hành vi trong các công cụ JavaScript gần đây đang thực hiện một số hỗ trợ cho phân lớp của mảng. –

4

Bạn có thể chỉ đơn giản là chỉ cần thêm chức năng trực tiếp đến đối tượng của bạn chứ không phải là nguyên mẫu:

var myArray = new Array(); 
myArray.myFunc = function(){ /* do stuff! */ }; 
myArray.myFunc(); 
+0

+1 thx. Tôi đã chọn câu trả lời của Elian làm cho câu trả lời chung chung hơn. – Christophe

Các vấn đề liên quan