Hướng dẫn javascript calculator using eval function - máy tính javascript sử dụng hàm eval

Tạo một máy tính nhắc nhở cho một biểu thức số học và trả về kết quả của nó.

Không cần phải kiểm tra biểu thức cho sự chính xác trong nhiệm vụ này. Chỉ cần đánh giá và trả lại kết quả.

Chạy bản demo

Hãy để sử dụng eval để tính toán biểu thức toán học:

let expr = prompt("Type an arithmetic expression?", '2*3+2');

alert( eval(expr) );

Người dùng có thể nhập bất kỳ văn bản hoặc mã nào mặc dù.

Để làm cho mọi thứ an toàn và chỉ giới hạn nó ở Arithmetics, chúng ta có thể kiểm tra expr bằng cách sử dụng biểu thức thông thường, để nó chỉ có thể chứa các chữ số và toán tử.

Nhưng tôi không thể nghĩ bất kỳ sự thay thế nào

Đối với một cái gì đó đơn giản như ví dụ của bạn, nơi bạn có chính xác hai đầu vào và một toán tử từ một danh sách bị ràng buộc (chỉ + trong ví dụ của bạn, nhưng tôi đoán bạn có ba người khác), bạn có thể sử dụng đối tượng điều phối hoặc Map:

const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);

Được rồi, hãy để Lừa bị nứt. Cách dễ nhất để viết một máy tính là không viết nó. Bản thân JavaScript đã là một máy tính, phải không? Các biểu thức toán học được trình thông dịch JavaScript đánh giá tự động, vì vậy nếu bạn viết một cái gì đó như

Biến result sẽ tham chiếu số 2.

Thậm chí tốt hơn, nó có khả năng xử lý ưu tiên của người vận hành - ví dụ như phép nhân luôn phải được thực hiện trước khi thêm và nếu bạn viết

Kết quả sẽ (chính xác) là 7, chứ không phải 9, mà một máy tính ngây thơ xử lý tất cả các hoạt động từ trái sang phải, bất kể điều gì, có thể đưa ra.

Đoàn làm việc

Vì vậy, ý tưởng chung là: Nếu bạn có một chuỗi chứa biểu thức toán học, như

const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
0, bạn có thể sử dụng
const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1 để đánh giá biểu thức đó và nhận được giá trị của nó. Mã duy nhất bạn phải viết là để xử lý đầu vào và đầu ra - phần khó của việc tính toán công cụ thực sự có thể được để lại cho trình thông dịch JavaScript.

Điều này thường có nghĩa là bạn phải làm như sau:

1.) Thiết lập một loạt các nút, vì vậy nhấp vào chúng sẽ thêm một ký tự vào trường đầu vào/đầu ra. Những ký tự đó là các số và hoạt động toán học cần thiết để tạo thành biểu thức toán học.Set up a bunch of buttons, so clicking on them will add a character to the input/output field. Those characters are the numbers and mathematical operations needed to form the mathematical expression.

2.) Thiết lập nút ‘Tính toán hoặc‘ = Nút, do đó nhấp vào nó sẽ đọc nội dung hiện tại của trường đầu vào/đầu ra, đánh giá chúng và ghi kết quả trở lại trường đầu vào/đầu ra.Set up a ‘calculate’ or ‘=’ button, so clicking on it will read the current contents of the input/output field, evaluate them, and write the result back to the input/output field.

Và đó là tất cả những gì có với nó. Ở đây, một ví dụ về cách bạn có thể làm điều đó:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

Máy tính đơn giảnDOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Simple Calculatortitle>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.js">script>
<script>

$ (function () {(function () {

& nbsp; & nbsp; // Thêm các thùng chứa vào DOM & NBSP; var $ calculator = $ ('', {id: 'máy tính'}). appendto ('body'); & nbsp; var $ input = $ ('', {id: 'input'}). appendto ($ máy tính); & nbsp; var $ nút = $ ('', {id: 'nút'}). appendto ($ máy tính);// Add containers to the DOM
  var $calculator = $('

', {id: 'calculator'}).appendTo('body');
  var $input = $('', {id: 'input'}).appendTo($calculator);
  var $buttons = $('
', {id: 'buttons'}).appendTo($calculator);

& nbsp; & nbsp; // Thêm nút vào DOM & NBSP; $ .each ('1234567890. =+-*/← C'.split (' '), function () {& nbsp; & nbsp; var $ nút = $ (' ', {text: this.toString () function () {& nbsp; & nbsp; & nbsp; // click nút xử lý & nbsp; & nbsp; & nbsp; switch ($ (this) .text ()) {& nbsp; & nbsp; & nbsp; & nbsp; // ' Chuỗi biểu thức, đánh giá nó, & nbsp; & nbsp; & nbsp; & nbsp; // và viết kết quả trở lại trường đầu vào/đầu ra. ; & nbsp; case '=': thử {$ input.val (eval ($ input.val ()));} Catch (e) {$ input.val ('error'); ; // 'C' sẽ xóa trường đầu vào/đầu ra & nbsp; & nbsp; & nbsp; 'Sẽ xóa ký tự cuối cùng khỏi trường đầu vào/đầu ra & nbsp; & nbsp; & nbsp; & nbsp; break; case' ← ': trả về $ input.val ($ input.val (). Thay thế (/.$/,' ') ); & nbsp; & nbsp; break; mặc định: $ input.val ($ input.val ()+ $ (this) .text ()); & nbsp; & nbsp; & nbsp; } & nbsp; & nbsp; }}). Phụ lục ($ nút); & nbsp; });});// Add buttons to the DOM
  $.each('1234567890.=+-*/←C'.split(''), function () {
    var $button = $('

& nbsp; #calculator {Border: 1px Solid; chiều rộng: 130px;} & nbsp; #input {Border: 1px Solid; Chiều cao: 20px; Chiều rộng: 114px; Biên độ: 5px; Đệm: 2px; Văn bản-Align: Phải;} & nbsp; #Buttons {lề: 5px;} & nbsp; nút {chiều rộng: 30px; Chiều cao: 30px;}

Tôi đã sử dụng jQuery ở đây, vì không có gì xảy ra ngoại trừ một chút thao túng DOM, điều này sẽ tẻ nhạt hơn khi sử dụng JavaScript đơn giản.

Đợi đã, có phải là Eval Evil Evil?its downsides:

Bạn có thể đã đọc ở đâu đó không bao giờ sử dụng

const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1, vì nó có vẻ bề ngoài, điều đó có nghĩa là gì. Tuyên bố chăn đó hơi khắc nghiệt -
const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1 chắc chắn không cung cấp AIDS cho trẻ nhỏ. Có một chút bù đắp quá mức đang diễn ra, bởi vì người mới bắt đầu đã lạm dụng triệt để
const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1 từ lâu, nhưng nó có cách sử dụng hợp pháp của nó, nếu bạn hiểu nhược điểm của nó:
: Dynamically generated code (and that’s what’s happening when using
const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1) is hard to debug. It won’t have line numbers, you can’t easily set breakpoints, and you’re generally forfeiting most of your debugging tools. That means that putting executable code into a string in one of your code files is never a good idea. There’s always — I repeat, always — a better way. Consider this example:

12345
2
3
4
5

// không làm điều đó như Thisvar Flies Like = {Time: 'Mũi tên', trái cây: 'Banana'}; for (Var Property in Flies Like) {& nbsp; eval
var fliesLike = {time: 'arrow', fruit: 'banana'};
for (var property in fliesLike) {
  eval('alert(property + " flies like: " + fliesLike.' + property + ')');
}

Rõ ràng, bất cứ ai viết đoạn mã đó đều học được rằng cú pháp phù hợp để truy cập các thuộc tính đối tượng là

const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
6, nhưng vì tên thuộc tính là biến, nên công việc giành được này - vì vậy họ đã sử dụng động tạo chuỗi
const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
7 và đánh giá nó. Và để có biện pháp tốt, họ đã ném toàn bộ lệnh vào chuỗi. Chỉ để chắc chắn.

Chỉ cần nhìn vào mớ hỗn độn đó, rõ ràng là điều đó khá xấu xí và nói chung là không tốt. Nếu chỉ có tác giả biết rằng các thuộc tính đối tượng cũng có thể được truy cập bằng dấu ngoặc, mã của chúng có thể là nhiều saner:

1234
2
3
4

var flies like = {thời gian: 'mũi tên', trái cây: 'chuối'}; cho (var thuộc tính trong ruồi) {& nbsp; ALERT (Thuộc tính + 'Ruồi như:' + FLIES like [Thuộc tính]);} fliesLike = {time: 'arrow', fruit: 'banana'};
for (var property in fliesLike) {
  alert(property + ' flies like: ' + fliesLike[property]);
}

Đó là một ví dụ tuyệt vời về sự thiếu hiểu biết dẫn đến ____ 11-lạm dụng, đây là thủ phạm chính cho danh tiếng khủng khiếp

const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1 có ngày hôm nay. Vì vậy, những gì một sử dụng hợp pháp? Hãy để xem tại sao điều này không phải là người: anh chàng đó biết rõ về việc sử dụng đối tượng nào, tài sản nào để truy cập và phải làm gì với nó. Vì vậy, chỉ cần làm điều đó, vì lợi ích của Chúa.

Mặt khác, máy tính của chúng tôi, tình huống khá khác biệt: nguồn gốc của những tính toán đó không phải là một số mã khác, nhưng đầu vào của người dùng, dẫn đến một chuỗi. Điều đó có nghĩa là chúng tôi (các lập trình viên) không đặt mã vào một chuỗi (điều này luôn luôn khủng khiếp và sai) - chúng tôi chỉ có quyền truy cập vào một chuỗi có chứa mã và để thực thi mã đó, không sao khi

const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1 chuỗi.

Các vấn đề bảo mật: Đây là lập luận chính cho

const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1 là xấu xa, mặc dù nhiều người sử dụng lập luận đó don don hoàn toàn hiểu chính xác những mối quan tâm bảo mật có liên quan ở đây.: This is the main argument for
const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1 being evil, although many people using that argument don’t fully understand exactly what security concerns are involved here.

Tôi muốn bạn là một trong những người làm, và nó thực sự khá đơn giản: bất cứ khi nào người dùng truy cập trang web của bạn, thì, đủ dễ dàng, hai bên liên quan: người dùng và trang web của bạn. Bạn có thể đặt tất cả JavaScript bạn muốn vào trang web của mình, nhưng bạn không thể gây hại - trình duyệt sẽ ngăn bạn truy cập bất kỳ dữ liệu người dùng nhạy cảm nào bên ngoài trang web của bạn (như hệ thống tệp của người dùng hoặc cookie mà người dùng nhận được từ những người dùng khác trang web). Mặt khác, người dùng có thể sử dụng bảng điều khiển hoặc tập lệnh người dùng tùy chỉnh của trình duyệt để chạy bất kỳ phần nào của JavaScript họ muốn trong khi trên trang web của bạn, nhưng họ cũng không thể gây hại - nó chạy cục bộ trong trình duyệt của họ và không có ai khác sẽ không bao giờ biết những gì họ đã làm.

Ở đây, nơi mà

const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1 xuất hiện, có thể chuyển đổi một chuỗi thành mã thực thi - và liệu mã đó có thể gây ra bất kỳ tác hại nào hay không phụ thuộc vào cả hai nơi mà nó đến và nơi mà nó sẽ đi:

A) Nếu nó đến từ bạn và đi đến người dùng, bạn đã làm sai. Bạn có toàn quyền kiểm soát mã của riêng mình, vì vậy, không cần phải

const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1. Điều đó nói rằng, bạn có thể gây hại, bởi vì bạn đã có thể chạy bất kỳ phần JavaScript tùy ý nào trong trình duyệt của người dùng, trong khi chúng có trên trang web của riêng bạn.If it comes from you and goes to the user, you’re doing it wrong. You have full control over your own code, so there’s no need to
const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1 anything. That said, you can’t do any harm, because you’re already able to run any arbitrary piece of Javascript in the user’s browser, while they are on your own website.

b) Nếu nó xuất phát từ người dùng và ở lại người dùng, cũng không thể làm hại. Người dùng đã có thể chạy bất kỳ phần JavaScript tùy ý nào trong trình duyệt của họ trong khi trên trang web của bạn. Đây là những gì mà xảy ra với máy tính của chúng tôi.If it comes from the user and stays at the user, no harm can be done either. The user is already able to run any arbitrary piece of Javascript in their browser while on your website. This is what’s happening with our calculator.

c) Nếu nó đến từ một dịch vụ web khác và đi đến người dùng, có khả năng gặp rắc rối: Trình duyệt của người dùng sẽ chạy nó với cùng một đặc quyền của bạn, điều đó có nghĩa là nó có thể truy cập và đánh cắp cookie mà người dùng nhận được từ trang web của bạn ( Cookie phiên tương đương với danh tính của người dùng trên trang web của bạn), theo dõi mỗi lần di chuyển của người dùng trên trang web của bạn và thường làm bất cứ điều gì có thể được thực hiện trên trang web của bạn - tất cả đều thuộc tên của người dùng. Chẳng hạn, nếu bạn cho phép người dùng đăng nhập để đăng nhận xét hoặc đặt hàng, thì đoạn mã đó có thể làm điều đó.If it comes from another web service and goes to the user, there’s potentially trouble: The user’s browser will run it with the same privileges your own code has, which means it can access and steal the cookies the user got from your website (the session cookie being tantamount to the user’s identity on your website), monitor the user’s every move on your website, and quite generally do anything that can be done on your website — all in the user’s name. For instance, if you allow logged in users to post comments or place an order, that piece of code can do just that.

Được rồi, vậy tại sao bạn thậm chí sẽ nghĩ về mã

const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1 đến từ một dịch vụ web khác? Thông thường, nó đã thực hiện để chuyển đổi chuỗi JSON thành một đối tượng để truy cập dữ liệu của bên thứ ba - ví dụ, bạn có thể muốn hiển thị một luồng ảnh từ Flickr trên trang web của mình, vì vậy bạn lấy dữ liệu ảnh dưới dạng JSON từ trang web của họ. Các trình duyệt mới hơn thực hiện một đối tượng JSON bản địa không cần sử dụng
const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1, nhưng vấn đề là, trường hợp này đi xuống để tin tưởng. Nếu bạn không tin tưởng một dịch vụ không được tiêm mã độc vào trang web của bạn, thì hãy sử dụng nó.

d) Nếu nó đến từ một người dùng và đi đến người dùng khác, thì chắc chắn gặp rắc rối. Tất cả các vấn đề được đề cập ở trên vẫn được áp dụng, chỉ bây giờ nó thực sự ngu ngốc khi tin tưởng, vì nguồn gốc của mã là một số người dùng tùy ý mà bạn không biết.If it comes from one user and goes to another user, there’s definitely trouble. All the issues mentioned above still apply, only now it’s really stupid to trust, since the source of the code is some arbitrary user you don’t know.

Về cơ bản, có hai cách để điều này có thể xảy ra: đầu tiên, bạn lưu đầu vào của người dùng trên máy chủ và cung cấp cho người dùng khác. Điều đó xảy ra mọi lúc - một người dùng viết một bình luận và một người dùng khác có thể đọc nó - và đó là lý do tại sao bất kỳ đầu vào người dùng nào sẽ xuất hiện trong một trình duyệt khác của người dùng phải được lọc kỹ lưỡng. Nếu bất kỳ đoạn mã thực thi nào làm cho nó thông qua, bạn sẽ bị lừa. Sử dụng

const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1 để tạo ra một đoạn mã thực thi từ một chuỗi có thể tự mình hoàn toàn vô hại là đặc biệt ngu ngốc trong trường hợp này. Thứ hai, bạn
const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1 một phần của truy vấn. Trong trường hợp này, nó đủ để dỗ người dùng khác nhấp vào một liên kết đã được chuẩn bị sẵn với một truy vấn độc hại hoặc gửi một hình thức độc hại từ một trang web khác, để gây hại. Ở đây, một lần nữa, nó đủ tệ để in bất kỳ phần chưa được lọc nào của truy vấn trở lại trang, và nó đặc biệt ngu ngốc khi
const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1.First, you save user input on the server and make it available to other users. That’s happening all the time — one user writes a comment and another user can read it — and that’s the reason why any user input that will end up in another user’s browser has to be thoroughly filtered. If any piece of executable code makes it through, you’re screwed. Using
const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1 to generate a piece of executable code from a string that might have been perfectly harmless on its own is particularly stupid in this case. Second, you
const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1 part of the querystring. In this case, it suffices to coax other users into clicking a link that has been prepped up with a malicious querystring, or into submitting a malicious form from another website, in order to do harm. Here, again, it’s bad enough to print any unfiltered piece of the querystring back to the page, and it’s particularly stupid to
const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1 it.

Tiếp theo là gì?

Được rồi, bây giờ chúng tôi đã thiết lập rằng cách tiếp cận đơn giản này không phải là xấu, vì những nhược điểm nghiêm trọng của

const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1 don lồng áp dụng, hãy để Lôi nhận được thật: nó cũng rất tốt.

Chẳng hạn, không có gì để ngăn người dùng nhập một chuỗi không đúng hình thức, như expr0, điều này sẽ gây ra lỗi khi cố gắng đánh giá nó. Chúng tôi có thể chống lại điều đó bằng cách lọc triệt để chuỗi đầu vào trước khi chuyển nó sang

const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1.filtering the input string before passing it to
const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1.

Mặc dù vậy, việc được hình thành tốt vẫn không có nghĩa là nó hợp lệ, ví dụ-expr2 trông giống như một biểu thức toán học hoàn toàn được hình thành hoàn toàn, nhưng nó vẫn giành được kết quả trong một số, vì không được phép chia 0. Chúng tôi có thể chống lại rằng bằng cách giới thiệu một số loại xử lý lỗi.error handling.

Điều gì sẽ xảy ra nếu chúng ta muốn thực hiện nhiều hơn chỉ là các hoạt động cơ bản, ví dụ expr3 (số mũ)? Có một toán tử JavaScript có thể được đặt giữa hai số để thực hiện điều đó - nó phải được thực hiện với expr4, điều đó có nghĩa là các nút của chúng tôi có thể chỉ cần thêm vào chuỗi đầu vào; Họ phải bằng cách nào đó thay đổi một cách hồi tố tùy thuộc vào những gì đã có trong đó và trên nút nào đã được nhấn - và đó là nơi mà rắc rối bắt đầu:

Số mũ có quyền ưu tiên cao hơn phép nhân và chúng tôi có thể chuyển đổi đầu vào nút expr5 thành chuỗi expr6, nhưng vấn đề là thế này: cho đến bây giờ, chúng tôi không phải quan tâm đến Thông dịch viên JavaScript xử lý điều đó. expr7 xuất hiện trước expr8 và JavaScript biết điều đó. Tuy nhiên, nếu chúng ta bắt đầu sử dụng các chức năng để biểu diễn các hoạt động toán học, đó, việc xử lý ưu tiên tích hợp sẽ bay ngay ngoài cửa sổ. Ví dụ, nếu một số hoạt động tùy chỉnh có mức độ ưu tiên thấp hơn expr7, chuỗi nút +0 sẽ phải được phân tích cú pháp đến +1 và không phải là +2.built-in precedence handling flies right out the window. If, for instance, some custom operation has lower precedence than expr7, the button sequence +0 would have to be parsed to +1, and not to +2.

Làm thế nào mã của chúng tôi sẽ biết về ưu tiên của nhà điều hành? Chúng tôi sẽ cần một số cấu trúc dữ liệu nơi chúng tôi có thể lưu trữ loại thông tin đó. Làm thế nào nó dịch nút nhấn vào một biểu thức hợp lệ không chỉ có thể được

const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1 mà còn tôn trọng sự ưu tiên của toán tử? Một số phân tích nặng và có khả năng xấu xí.data structure where we can store that sort of information. How would it translate button presses into a valid expression that can not only be
const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1ed but that also respects operator precedence? Some heavy and potentially ugly parsing.

Câu trả lời cho hai câu hỏi cuối cùng cho thấy, trong tương lai, chúng ta nên bỏ qua cách tiếp cận

const operatons = {
    "+": (a, b) => a + b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    // ...
};
// Using it...
const operation = operation[operator];
if (!operation) {
    throw new Error(`Invalid operator "${operator}"`);
}
const result = operation(input1, input2);
1 và thay vào đó nên thử để đưa ra mã cho một máy tính thực tế biết những gì nó đang làm, trái ngược với người dịch giữa người dùng Đầu vào và trình thông dịch JavaScript mà chúng tôi đã tạo cho đến nay.actual calculator that knows what it’s doing, as opposed to the translator between the user’s input and the Javascript interpreter we’ve created so far.

Và đó chính xác là những gì chúng tôi sẽ làm tiếp theo.

Tôi có thể sử dụng eval cho máy tính không?

Vâng, điều đó là có thể thực hiện được, và bạn không có nguy cơ phải bán cái quái của mình để được cộng đồng mã hóa tha thứ.Chỉ là việc sử dụng một eval sẽ không cho phép bạn có được sự thành thạo tính toán và đôi khi sẽ cho bạn kết quả gớm ghiếc, vì nhị phân chỉ ra cho bạn trong nhận xét của nó., and you don't risk having to sell your heck out to be forgiven by the coding community. It's just that the use of an eval will not allow you to obtain a mastery of the calculation and will sometimes give you abhorrent results, as Binary indicates to you in its comment.

Eval () làm gì trong JavaScript?

Hàm Eval () đánh giá mã JavaScript được biểu thị dưới dạng chuỗi và trả về giá trị hoàn thành của nó.Nguồn được phân tích cú pháp như một kịch bản.evaluates JavaScript code represented as a string and returns its completion value. The source is parsed as a script.

Làm thế nào để bạn mã hóa một máy tính trong JavaScript?

const number1 = parsefloat (nhắc ('nhập số đầu tiên:'));const number2 = parsefloat (nhắc ('nhập số thứ hai:'));để kết quả;// Tuyên bố của biến.// Sử dụng nếu, otherif và từ khóa khác để xác định điều kiện máy tính trong JavaScript.

$$ eval là gì?

Phương thức $$ eval ().Phương thức này chạy Array.From (Document.QuerySelectorall (bộ chọn)) trong trang và chuyển kết quả là đối số đầu tiên cho PageFunction.This method runs Array. from(document. querySelectorAll(selector)) within the page and passes the result as the first argument to the pageFunction .