.Map () đang làm gì trong tình huống này?


95

Sử dụng Bảng điều khiển Chrome, đây là đầu vào và đầu ra của tôi:

[0].map(Array);

[[0, 0, [0]]]; // output

Chuyện gì đang xảy ra ở đây?

BIÊN TẬP

Lý do điều này khiến tôi tò mò là vì một cái gì đó như

[0].map(String);

Sẽ trở lại

["0"];

Và không

["0", "0", "String"]

34
Tôi cho rằng vì anh ấy luôn cần một số WTF Javascript để cảm thấy hạnh phúc
npst 15/09/17

12
Ồ, nó chỉ là một biến thể ít wtf-y hơn của['10', '10', '10'].map(parseInt)
gronostaj, 15/09/17

2
Một .map()hành vi kỳ lạ khác : stackoverflow.com/questions/14528397/… Nói chung, bạn phải cẩn thận khi sử dụng .map()với các hàm có nhiều đối số.
Barmar

2
Just do[0].map(console.log)
Bergi

1
@Jacksonkr: Cảm ơn vì câu trả lời. Tôi nghĩ rằng nó đã diễn ra như thế này: Tôi đã viết một bình luận, giải thích rằng việc nhìn thấy JS WTFs làm cho tôi hạnh phúc và tôi không phải sử dụng ngôn ngữ này thường xuyên. Có người hỏi tại sao tôi sẽ xem các câu hỏi JS nếu tôi không thích ngôn ngữ này. npst đã trả lời và hai bình luận đầu tiên đã bị xóa. Thật buồn cười là bình luận của anh ấy vẫn được ủng hộ, vâng.
Eric Duminil

Câu trả lời:


123

Các .map()chức năng đang kêu gọi các Array()chức năng với ba đối số, giá trị của các phần tử mảng đó là 0, chỉ số của phần tử đó, cũng 0, và một tham chiếu đến toàn bộ mảng.

Vì vậy, nó giống như làm điều này:

var a = [0];
var index = 0
Array(a[index], index, a);   // create array with three elements

Mảng được trả về Array()sau đó sẽ trở thành phần tử đầu tiên của mảng .map()tạo ra, do đó, cấp độ lồng thêm vào [[0, 0, [0]]]kết quả của bạn .

CHỈNH SỬA liên quan đến chỉnh sửa của bạn: khi bạn nói [0].map(String);điều đó dẫn đến String()việc được gọi với ba đối số giống nhau String(a[index], index, a), nhưng String()hàm bỏ qua tất cả trừ đối số đầu tiên, trong khi Array()sử dụng tất cả các đối số được cung cấp.


39

Thứ nhất , Arraycó thể được sử dụng như một hàm để tạo mảng:

var arr = Array(1, 2, "Hello");

console.log(arr); // [1, 2, "Hello"]

Thứ hai , mapchuyển ba tham số cho lệnh gọi lại của nó: phần tử, chỉ số của nó từ mảng và chính mảng.

Vì vậy , vì mảng của bạn chứa một phần tử, dòng:

[0].map(Array);

tương đương với:

[Array(0, 0, [0])];     // the element 0 in the original array will be mapped into Array(0, 0, [0])

6

Sau khi bạn cập nhật câu hỏi. Các câu trả lời khác cung cấp cho bạn thông tin về bản đồ

Để trả lời tại sao mảng và chuỗi lại khác nhau, hãy tìm các hàm tạo

Hàm tạo chuỗi chấp nhận 1 tham số Chuỗi (điều) trong khi mảng mới Mảng (phần tử0, phần tử1 [, ... [, phần tửN]])


2
Đó cũng là lý do tại sao .map(Number)chuyển đổi mọi mục thành một số thay vì trả lại một cái gì đó giống như [3, 2, [4, 1, 3]]cho mọi mục.
user4642212 15/09/17

@Xufox có câu trả lời là ở nhà xây dựng :)
Volodymyr Bilyachat

4

Cuộc gọi này

[0].map(Array);

cung cấp cho bạn kết quả giống như khi bạn viết một cái gì đó như thế này:

[0].map(function (value, index, array) {
    return Array(value, index, array);
})

Bản đồ chức năng đang kêu gọi Mảng chức năng với ba thông số: giá trị của nguyên tố, chỉ số của phần tử và toàn bộ mảng. Lệnh gọi này Arraytrả về cho bạn mảng có 3 phần tử: value (số 0), index (số 0), whole array ( [0]).

Và mảng mới này được bao bọc trong Mảng ban đầu, vì bạn đã ánh xạ phần tử ban đầu (số 0) thành phần tử mới (mảng 3 phần tử)

Lưu ý: Bạn có thể quen chỉ sử dụng tham số đầu tiên như trong

array.map(function (a) { return a * a; });

hoặc chỉ sử dụng hai để có được chỉ mục

array.map(function (item, index) { return "index=" + index + ", value=" + item; });

Nhưng bạn cần nhớ rằng mapvẫn cung cấp 3 tham số bạn chỉ cần bỏ qua chúng trong hàm gọi lại của mình. Đó cũng là lý do tại sao mã như:

[0].map(String);

trả lại

["0"]

Đó là bởi vì hàm String chỉ quan tâm đến tham số đầu tiên và bỏ qua các tham số khác được truyền vào. Nếu bạn gọi

String(11, "Some", "other", "ignored", "parameters")

bạn vẫn sẽ nhận được

"11"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.