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ông là Array
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?
Trả lời
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
, reverse
và sort
.
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, toString
và toLocaleString
, 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
.
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
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
@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
Đ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.
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
Rex và Anurag, cả hai điểm tốt. – pr1001
@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 :) –
đố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.
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
Đố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.
- 1. JavaScript: tại sao thay đổi biến đối số thay đổi mảng `đối số` '?
- 2. Đối tượng hàm đối số trong Node.js khác với JavaScript của JavaScript
- 3. Javascript: mảng đối số không được chấp nhận?
- 4. JavaScript - Đếm bản sao trong một mảng các đối tượng
- 5. Tại sao tính năng Addable của Scala bị phản đối?
- 6. Tại sao mảng typeof với đối tượng trả về "Đối tượng" chứ không phải "Mảng"?
- 7. Tại sao JavaScript nguyên thủy không phải là đối tượng của đối tượng?
- 8. Tại sao hàm tạo EnumMap cần đối số lớp?
- 9. Tại sao == đúng đối với một số đối tượng Integer?
- 10. Tại sao tôi cần xác định loại đối số mẫu của một hàm mẫu ở đây?
- 11. Javascript hàm setInterval với đối số
- 12. Nhận số đối số (hoặc thậm chí cả tên) của đối tượng hàm javascript
- 13. mảng javascript đối tượng
- 14. Đối số siêu() của Python: tại sao không siêu (obj)?
- 15. Javascript eval() cho hàm có đối số
- 16. Đối số mảng có được chuyển đến một hàm không phải là một con trỏ không?
- 17. Tại sao các đối số trong JavaScript không phải trước từ khóa var?
- 18. javascript: chuyển một đối tượng làm đối số cho hàm onclick bên trong chuỗi
- 19. đối tượng JavaScript đẩy vào một mảng
- 20. Trong Python, tại sao một hàm có thể sửa đổi một số đối số như được người gọi cảm nhận, nhưng không phải là những đối số khác?
- 21. Chuyển các đối số hàm tới một hàm bên trong?
- 22. JavaScript: hàm trả về một đối tượng
- 23. Tại sao áp dụng() ở đây chỉ có một đối số thay vì hai đối số?
- 24. JavaScript - đối số không hợp lệ IE8
- 25. Cách chuyển mảng làm đối số cho hàm trong Bash
- 26. Xử lý đối số mảng của execvp?
- 27. Thuộc tính của đối tượng hàm Javascript
- 28. Tại sao không thể lấy Py_buffer từ đối tượng mảng?
- 29. Tại sao các tên đối số hàm không quan trọng trong khai báo C++?
- 30. Tại sao mẫu người quan sát bị phản đối?
Đâ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. –