2010-07-14 57 views
42

Vì có vẻ như điều đầu tiên mọi người làm là chuyển đổi arguments thành một mảng thực, tôi quan tâm đến lý do tại sao các tác giả và người triển khai ngôn ngữ Javascript quyết định và tiếp tục nghĩ rằng arguments nên khôngArray thực. Tôi không có ý đó là flamebait, tôi chân thành quan tâm đến suy nghĩ đằng sau nó. Vì hàm này được gọi tự nhiên khi bạn ở trong cơ thể của nó, tôi không nghĩ rằng đó là vì các đối tượng arguments đang tham chiếu có thể thay đổi, giống như một số kết quả DOM ...Tại sao đối số của hàm không phản đối một mảng trong Javascript?

+0

Đây không phải là vấn đề trong ES6. Bạn có thể sử dụng [tham số còn lại] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters), đây là một mảng thực. –

Trả lời

42

phỏng đoán của tôi:

Khái niệm về đối tượng arguments đã có mặt trên ngôn ngữ kể từ khi bắt đầu, thậm chí nó còn được mô tả trong ECMAScript First Edition Standard (PDF).

Trong phiên bản ECMAScript đó, Array.prototype thực sự là cơ bản, đối tượng mảng chứa chỉ có 4 phương pháp!: toString, join, reversesort.

Tôi nghĩ rằng đó là một trong những lý do chính khiến họ thực hiện arguments để kế thừa từ Object.prototype, tại thời điểm đó, các phương pháp Array không quá hữu ích.

Nhưng đối tượng Array.prototype đã được mở rộng trong các phiên bản tiếp theo của tiêu chuẩn, bây giờ ES5, các đối tượng Mảng có các phương pháp như map, reduce, every, some, vv, đó là thật sự mạnh mẽ.

Năm ngoái, đã có một đề xuất trong ES5 để làm cho arguments được kế thừa từ Array.prototype, trong giai đoạn dự thảo của tiêu chuẩn, nhưng đã bị hủy bỏ thời gian sau đó.

Trong những bản thảo, arguments thừa hưởng từ Array.prototype, nhưng để tương thích ngược với ES3, đối tượng arguments đã định nghĩa hai thuộc tính riêng, toStringtoLocaleString, cả hai trỏ đến các phương pháp tương tự trên Object.prototype, nhưng cuối cùng, Ủy ban quyết định giữ kế thừa từ Object.prototype.

+14

phỏng đoán? có vẻ như bạn đã có mặt trong tất cả các cuộc họp ủy ban đó .. lol – Anurag

+5

Và những người đã không biết về điều đó: http://www.slideshare.net/douglascrockford/newandimproved, kết thúc tốt đẹp btw +1. Nhưng nó không cho bạn biết ** tại sao ** ủy ban "** tiếp tục ** nghĩ rằng' đối số' không phải là một 'Mảng' thực sự" – galambalazs

+2

@galambalazs: IMO lý do tại sao ủy ban quyết định rằng, đó là về sự sợ hãi phá vỡ web *, tiêu chuẩn ES5 được thiết kế rất cẩn thận, tránh bất kỳ thay đổi căn bản nào, trên thực tế không có cú pháp mới nào được đưa vào ngôn ngữ. Đề nghị tôi nói về, IIRC đã bị loại bỏ vì họ thảo luận về các trường hợp * cạnh cực * không tương thích, chẳng hạn như định nghĩa lại 'Object.prototype'. Chúng ta sẽ thấy, có lẽ trong tương lai ... – CMS

5

Điều quan trọng cần lưu ý là không có một trong những nhà thiết kế hiện tại, chúng tôi chỉ thực sự có thể phỏng đoán được lý do tại sao. Nhưng chúng tôi có thể đưa ra một số lý do chính đáng ... đây là của tôi:

Từ quan điểm của hàm, một lý do có thể là vì bạn không thể - rõ ràng - thực sự thay đổi các đối số được chuyển vào bạn. Bạn có thể thay đổi một mảng đại diện cho các đối số được truyền vào bạn, nhưng các đối số khi chúng được thông qua được đặt trong đá trước khi bạn nhận được phạm vi thực thi.

Bạn có thể ghép nối, dice và pop mảng, và nếu bạn đã làm điều đó đối tượng arguments sau đó bạn chỉ hủy hoại những gì là khái niệm một cấu trúc bất biến (khuôn mặt buồn!). Thiết kế của đối tượng đối số thực là gần gũi hơn với một loại JavaScript bất biến có thể cung cấp.

Nó tương tự như tham số chuỗi truy vấn. Bạn nhận được một bộ sưu tập được gửi cho bạn bởi khách hàng gửi yêu cầu. Đó là một phần của thông tin yêu cầu, đã được thiết lập và thực hiện.

+4

Tôi không chắc liệu tôi có hoàn toàn đồng ý với lý do tại đây hay không. 'arguments' chỉ là một đối tượng, và mặc dù chúng ta không thể thay đổi một cách kỹ thuật các đối số thực, chúng ta có thể làm bất cứ điều gì chúng ta muốn đối tượng' arguments' hoặc các đối số riêng lẻ mà nó biểu diễn thông qua các chỉ mục mảng - 'arguments [0]', ' các đối số [1] ', ... Tại sao nó không được tạo ra một' Mảng' sau đó, hoặc được đưa ra một giao diện giống như mảng vẫn đáng để suy nghĩ. Cùng một vấn đề áp dụng cho NodeList's. – Anurag

+0

Rex và Anurag, cả hai điểm tốt. – pr1001

+0

@Anurag Tôi không nhất thiết không đồng ý ... như tôi đã nói, chúng tôi chỉ có thể phỏng đoán tại sao, và đây là lý thuyết của tôi :) –

2

đối số không chỉ trả lại đối số. Nó trả về đối tượng callee và mảng các đối số. Nếu nó chỉ là một mảng, phần tử đầu tiên có thể là đối tượng callee và khó hiểu hơn.

+0

Có lẽ câu hỏi sẽ là, tại sao không có một đối tượng 'callee' riêng biệt? Tại sao phải là tài sản của 'đối số'? – pr1001

26

Đối tượng đối số có tính năng rất khác thường khi các phần tử giống mảng của nó là từ đồng nghĩa cho các biến cục bộ chứa đối số hàm. Ví dụ:

function f(x) { 
    console.log(arguments[0]); // Displays the initial value of the argument x 
    x = 5;      // Changes the value of the local variable x 
    console.log(arguments[0]); // Now displays 5 
} 

Tôi luôn có ấn tượng rằng "hành vi ma thuật" này là lý do tại sao arguments không phải là một mảng.

+0

Đúng, nhưng tôi cũng có thể có 'hàm a() {console.log (đối số)}; a (1, 2, 3); '... – pr1001

+0

Có, hành vi này chỉ áp dụng khi bạn đã đặt tên đối số. –

+2

+1 - Đó là khá darn huyền diệu ... – gnarf

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