Câu trả lời đơn giản cho câu hỏi của bạn là Math.random()
vi phạm quy tắc số 2.
Nhiều câu trả lời khác ở đây đã chỉ ra rằng sự hiện diện của Math.random()
nghĩa là chức năng này không thuần túy. Nhưng tôi nghĩ điều đáng nói là tại sao các Math.random()
chức năng lại sử dụng nó.
Giống như tất cả các trình tạo số giả ngẫu nhiên, Math.random()
bắt đầu bằng giá trị "hạt giống". Sau đó, nó sử dụng giá trị đó làm điểm bắt đầu cho một chuỗi các thao tác bit cấp thấp hoặc các thao tác khác dẫn đến kết quả đầu ra không thể đoán trước (nhưng không thực sự ngẫu nhiên ).
Trong JavaScript, quá trình liên quan phụ thuộc vào việc triển khai và không giống như nhiều ngôn ngữ khác, JavaScript không cung cấp cách nào để chọn hạt giống :
Việc thực hiện chọn hạt giống ban đầu cho thuật toán tạo số ngẫu nhiên; nó không thể được chọn hoặc thiết lập lại bởi người dùng.
Đó là lý do tại sao hàm này không thuần túy: JavaScript về cơ bản đang sử dụng một tham số hàm ngầm mà bạn không có quyền kiểm soát. Nó đọc thông số đó từ dữ liệu được tính toán và lưu trữ ở nơi khác, và do đó vi phạm quy tắc số 2 trong định nghĩa của bạn.
Nếu bạn muốn biến đây thành một hàm thuần túy, bạn có thể sử dụng một trong các trình tạo số ngẫu nhiên thay thế được mô tả ở đây . Gọi máy phát điện đó seedable_random
. Nó nhận một tham số (hạt giống) và trả về một số "ngẫu nhiên". Tất nhiên, con số này không thực sự ngẫu nhiên chút nào; nó được xác định duy nhất bởi hạt giống. Đó là lý do tại sao đây là một chức năng thuần túy. Đầu ra của seedable_random
chỉ là "ngẫu nhiên" theo nghĩa là khó dự đoán kết quả dựa trên đầu vào.
Phiên bản thuần túy của hàm này sẽ cần có ba tham số:
function test(min, max, seed) {
return seedable_random(seed) * (max - min) + min;
}
Đối với bất kỳ bộ ba (min, max, seed)
tham số đã cho nào, điều này sẽ luôn trả về cùng một kết quả.
Lưu ý rằng nếu bạn muốn đầu ra của seedable_random
là thực sự ngẫu nhiên, bạn sẽ cần phải tìm một cách để ngẫu nhiên hạt giống! Và bất kỳ chiến lược nào bạn đã sử dụng chắc chắn sẽ không thuần túy, bởi vì nó sẽ yêu cầu bạn thu thập thông tin từ một nguồn bên ngoài chức năng của bạn. Như mtraceur và jpmc26 nhắc nhở tôi, điều này bao gồm tất cả các phương pháp tiếp cận vật lý: bộ tạo số ngẫu nhiên phần cứng , webcam có nắp thấu kính , bộ thu nhiễu khí quyển - thậm chí cả đèn dung nham . Tất cả những điều này liên quan đến việc sử dụng dữ liệu được tính toán và lưu trữ bên ngoài hàm.
Math.random()
thay đổi trạng thái của RNG.