Đây là một bài viết giải thích điều này thực sự tốt. Tôi đã sao chép một số điểm chính bên dưới. http://www.javascriptkit.com/javatutors/arrayprototypeslice.shtml
Đối với mảng, hãy nhớ rằng bạn có thể gọi hàm slice để nhận mảng phụ.
var abc = [1,2,3,4,5];
abc.slice(0); //[1,2,3,4,5]
abc.slice(1,3); //[2,3]
Vì đối số đối số chỉ là mảng, không thực sự là mảng. Hàm call()/apply() về cơ bản chỉ "mượn" hàm slice từ Array và sử dụng nó trên đối tượng Argument và thậm chí bạn có thể chuyển các tham số vào hàm slice giống như tác động lên mảng.
var myobject ={ // array-like collection
length: 4,
'0': 'zero',
'1': 'one',
'2': 'two',
'3': 'three'
}
var myarray = Array.prototype.slice.call(myobject)
// returns myobject as a true array: ["zero", "one", "two", "three"]
var myarray = Array.prototype.slice.call(myobject, 1)
// returns ["one", "two", "three"]
Câu hỏi còn lại là lý do tại sao chúng tôi gọi slice() trên đối tượng mẫu của mảng thay vì một mảng. Lý do là vì đây là tuyến đường trực tiếp nhất để truy cập vào phương thức slice() của Array khi đó là tất cả những gì chúng ta quan tâm; chúng ta có thể lần đầu tiên tạo ra một thể hiện mảng, nhưng đó là kém hiệu quả và có lẽ sâu sắc hơn:
var myarray = new Array().prototype.slice.call(myobject) // less efficient
Eh ...? Tại sao bạn lại giả định điều đó? Mỗi phép lặp chỉ xử lý phần tử đầu tiên, và sau đó nó tự gọi nó với phần còn lại cho đến khi không còn phần tử nào. Tôi không thực sự chắc chắn về phiên bản của bạn. – mpen
Oh..nevermind. Bởi vì chức năng nặc danh ... bạn nói đúng rồi, ngoại trừ nó vẫn không được phép chuyển qua phần tử đầu tiên .. nó được cho là vượt qua tất cả trừ cái đầu tiên. – mpen
@Mark: Bạn có 2 chức năng. Có lẽ tôi sai, nhưng tôi đã giải thích câu hỏi của bạn khi muốn truyền vào 'arguments' từ' runScripts() '* vào * callback mà bạn đang chuyển tới' executeScript'. Nó không phải là một giả định kỳ lạ để làm vì bạn đang tham chiếu 'arguments [0]' * bên ngoài * gọi lại, sau đó cố gắng '.shift()' * bên trong * gọi lại. – user113716