2014-04-04 16 views
10

tôi thấy cách này mát mẻ của việc sử dụng phương pháp Array.prototype.filter để loại bỏ tất cả các phi số từ một chuỗi, nhưng tôi không hoàn toàn chắc chắn làm thế nào nó bằng cách sử dụng nguyên mẫu Number để đạt được điều này:'Số' trong Array.prototype.filter (Số) hoạt động như thế nào?

var arr = '75number9'; 

arr.split(/[^\d]/).filter(Number); // returns [75, 9] 

Khi tôi kiểm tra typeof Number tôi nhận được trở lại 'function'. Chuyện gì đang xảy ra ở đây?

Thêm vào sự nhầm lẫn của tôi là nếu tôi thay thế Number bằng String, kết quả sẽ giống nhau. Nó vẫn làm việc!

arr.split(/[^\d]/).filter(String); // returns [75, 9] 

ArrayObject như thông số, mặt khác, trở về này:

["75", "", "", "", "", "", "9"] 

Rất tò mò muốn hiểu điều này!

+0

một số loại có thể hoạt động. ['Chức năng đối tượng (thực hiện [[Gọi]] trong điều khoản ECMA-262) \t" chức năng "'] (https: //developer.mozilla.org/en-US/docs/Web/JavaScript/Tham chiếu/Toán/typeof) – 13ruce1337

+0

@ 13ruce1337: Tất cả "loại" là hàm, vì trong javascript một lớp và hàm tạo là một và giống như – Eric

+0

@Eric tôi vừa mới phá vỡ não một vài giây trước nghĩ rằng ... cảm ơn cho xác nhận. – 13ruce1337

Trả lời

9

Number là hàm (hàm tạo) cố gắng trả về một số. Cung cấp cho nó một số hoặc một chuỗi có thể được phân tích cú pháp thành một số và nó trả về số đó. Cung cấp cho nó cái gì khác, và nó trả về NaN.

Bộ lọc trả về giá trị mà hàm gọi lại (trong trường hợp này là Number) trả về giá trị trung thực. Các số là != 0!= NaN là sự thật và do đó được trả về.

Như vậy, ví dụ bạn không trả lại 0 giá trị:

var arr = '75number0'; 
arr.split(/[^\d]/).filter(Number); 
// ["75"] 

Chú ý rằng các giá trị của mảng được trả về vẫn là chuỗi. Nếu chúng ta muốn họ được con số này, chúng ta có thể sử dụng map():

arr.split(/[^\d]/).filter(Number).map(Number); 
// [75, 9] 

Trong trường hợp sử dụng String constructor thay vì Number, nó hoạt động vì String đang trở lại chuỗi rỗng cho chuỗi rỗng nó được đưa ra, và có sản phẩm nào các chuỗi ('') bị lỗi giống như 0.

+0

+1 để đề cập đến hình ảnh xác nhận rằng điều này phá vỡ kỳ vọng cho '" 0 "'. –

+0

Tốt bắt! Câu hỏi sau đó tiếp tục yêu cầu tổng số các kết quả, vì vậy trong trường hợp này, 0 sẽ không cần thiết, nhưng cũng được thực hiện :) –

+0

+1. Tôi đã học được một cái gì đó mới ngày hôm nay. – Andy

1
> var arr = '75number9'; 
> arr = arr.split(/[^\d]/) 
> arr 
["75", "", "", "", "", "", "9"] 

Number là hàm tạo cho loại đóng hộp Number. Đối với một số lý do, nó cũng là có thể sử dụng như một chức năng:

> Number("") 
0 
> Number("75") 
75 

filter giữ yếu tố mà các kết quả gọi trong một giá trị không falsey. Khi chuỗi rỗng được truyền, nó trả về 0, đó là falsey, vì vậy các chuỗi rỗng bị loại bỏ

String, khi đưa ra một đối số chuỗi, không làm gì ngoài trả về nó. Kể từ khi "" là falsey, filter từ chối chuỗi rỗng một lần nữa.

+1

Hàm xây dựng _are_. Xem spec cho hàm 'Number'. – SLaks

+0

@SLaks: Thật vậy, nhưng nó không bình thường đối với một nhà xây dựng có giá trị trả lại – Eric

+1

"Vì một số lý do, nó cũng có thể sử dụng như một hàm" Lý do là đặc điểm kỹ thuật. Xem [15.7.1 Constructor được gọi là hàm] (http://es5.github.io/#x15.7.1), cụ thể hơn [15.7.1.1 Number (\ [value \])] (http: // es5.github.io/#x15.7.1.1). –

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