From 68a78857bdbfee769c27bc4d0909d60cc7495300 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Sat, 11 Mar 2023 09:26:48 +0700 Subject: [PATCH 01/83] Update article.md --- .../03-closure/article.md | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/article.md b/1-js/06-advanced-functions/03-closure/article.md index 199887063..3d646388a 100644 --- a/1-js/06-advanced-functions/03-closure/article.md +++ b/1-js/06-advanced-functions/03-closure/article.md @@ -1,75 +1,75 @@ -# Variable scope, closure +# Phạm vi biến, đóng kín -JavaScript is a very function-oriented language. It gives us a lot of freedom. A function can be created at any moment, passed as an argument to another function, and then called from a totally different place of code later. +JavaScript là một ngôn ngữ rất hướng hàm. Nó cho chúng ta rất nhiều tự do. Một hàm có thể được tạo bất cứ lúc nào, được chuyển dưới dạng đối số cho một hàm khác và sau đó được gọi từ một vị trí mã hoàn toàn khác sau đó. -We already know that a function can access variables outside of it ("outer" variables). +Chúng ta đã biết rằng một hàm có thể truy cập các biến bên ngoài nó (các biến "bên ngoài"). -But what happens if outer variables change since a function is created? Will the function get newer values or the old ones? +Nhưng điều gì sẽ xảy ra nếu các biến bên ngoài thay đổi kể từ khi một hàm được tạo? Hàm sẽ nhận giá trị mới hơn hay giá trị cũ? -And what if a function is passed along as a parameter and called from another place of code, will it get access to outer variables at the new place? +Và điều gì sẽ xảy ra nếu một hàm được truyền dưới dạng tham số và được gọi từ một vị trí khác của mã, liệu nó có được truy cập vào các biến bên ngoài ở vị trí mới không? -Let's expand our knowledge to understand these scenarios and more complex ones. +Hãy mở rộng kiến thức của chúng ta để hiểu những tình huống này và những tình huống phức tạp hơn. -```smart header="We'll talk about `let/const` variables here" -In JavaScript, there are 3 ways to declare a variable: `let`, `const` (the modern ones), and `var` (the remnant of the past). +```smart header="Chúng ta sẽ nói về các biến `let/const` ở đây" +Trong JavaScript, có 3 cách để khai báo một biến: `let`, `const` (cách hiện đại) và `var` (phần còn lại của quá khứ). -- In this article we'll use `let` variables in examples. -- Variables, declared with `const`, behave the same, so this article is about `const` too. -- The old `var` has some notable differences, they will be covered in the article . +- Trong bài viết này, chúng ta sẽ sử dụng các biến `let` trong các ví dụ. +- Các biến, được khai báo bằng `const`, hoạt động giống nhau, vì vậy bài viết này cũng nói về `const`. +- `var` cũ có một số điểm khác biệt đáng chú ý, chúng sẽ được đề cập trong bài viết . ``` -## Code blocks +## Khói mã -If a variable is declared inside a code block `{...}`, it's only visible inside that block. +Nếu một biến được khai báo bên trong khối mã `{...}`, thì nó chỉ hiển thị bên trong khối đó. -For example: +Ví dụ: ```js run { - // do some job with local variables that should not be seen outside + // thực hiện một số công việc với các biến cục bộ không nên nhìn thấy bên ngoài - let message = "Hello"; // only visible in this block + let message = "Xin chào"; // chỉ hiển thị trong khối này - alert(message); // Hello + alert(message); // Xin chào } -alert(message); // Error: message is not defined +alert(message); // Lỗi: tin nhắn không xác định ``` -We can use this to isolate a piece of code that does its own task, with variables that only belong to it: +Chúng ta có thể sử dụng điều này để cô lập một đoạn mã thực hiện nhiệm vụ riêng của nó, với các biến chỉ thuộc về nó: ```js run { - // show message - let message = "Hello"; + // hiển thị tin nhắn + let message = "Xin chào"; alert(message); } { - // show another message - let message = "Goodbye"; + // hiển thị một tin nhắn khác + let message = "Tạm biệt"; alert(message); } ``` -````smart header="There'd be an error without blocks" -Please note, without separate blocks there would be an error, if we use `let` with the existing variable name: +````smart header="Sẽ có lỗi nếu không có khối" +Hãy lưu ý, nếu không có các khối riêng biệt sẽ xảy ra lỗi, nếu chúng ta sử dụng `let` với tên biến hiện có: ```js run -// show message -let message = "Hello"; +// hiển thị tin nhắn +let message = "Xin chào"; alert(message); -// show another message +// hiển thị một tin nhắn khác *!* -let message = "Goodbye"; // Error: variable already declared +let message = "Tạm biệt"; // Lỗi: biến đã được khai báo */!* alert(message); ``` ```` -For `if`, `for`, `while` and so on, variables declared in `{...}` are also only visible inside: +Đối với `if`, `for`, `while`, v.v., các biến được khai báo trong `{...}` cũng chỉ hiển thị bên trong: ```js run if (true) { From 6df7986d72a2e903d58094a8268045ba4856ff06 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Sat, 11 Mar 2023 10:14:50 +0700 Subject: [PATCH 02/83] Update article.md --- .../03-closure/article.md | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/article.md b/1-js/06-advanced-functions/03-closure/article.md index 3d646388a..23894cd1d 100644 --- a/1-js/06-advanced-functions/03-closure/article.md +++ b/1-js/06-advanced-functions/03-closure/article.md @@ -73,58 +73,58 @@ alert(message); ```js run if (true) { - let phrase = "Hello!"; + let phrase = "Xin chào!"; - alert(phrase); // Hello! + alert(phrase); // Xin chào! } -alert(phrase); // Error, no such variable! +alert(phrase); // Lỗi, không có biến như vậy! ``` -Here, after `if` finishes, the `alert` below won't see the `phrase`, hence the error. +Ở đây, sau khi `if` kết thúc, `alert` bên dưới sẽ không thấy `phrase`, do đó xảy ra lỗi. -That's great, as it allows us to create block-local variables, specific to an `if` branch. +Điều đó thật tuyệt, vì nó cho phép chúng ta tạo các biến cục bộ khối, dành riêng cho một nhánh `if`. -The similar thing holds true for `for` and `while` loops: +Điều tương tự cũng đúng với các vòng lặp `for` và `while`: ```js run for (let i = 0; i < 3; i++) { - // the variable i is only visible inside this for + // biến i chỉ hiển thị bên trong cái này cho alert(i); // 0, then 1, then 2 } -alert(i); // Error, no such variable +alert(i); // Lỗi, không có biến như vậy ``` -Visually, `let i` is outside of `{...}`. But the `for` construct is special here: the variable, declared inside it, is considered a part of the block. +Về mặt trực quan, `let i` nằm ngoài `{...}`. Nhưng cấu trúc `for` ở đây đặc biệt: biến, được khai báo bên trong nó, được coi là một phần của khối. -## Nested functions +## Các hàm lồng nhau -A function is called "nested" when it is created inside another function. +Một hàm được gọi là "lồng nhau" khi nó được tạo bên trong một hàm khác. -It is easily possible to do this with JavaScript. +Có thể dễ dàng làm điều này với JavaScript. -We can use it to organize our code, like this: +Chúng ta có thể sử dụng nó để sắp xếp mã của ta, như thế này: ```js function sayHiBye(firstName, lastName) { - // helper nested function to use below + // hàm lồng nhau của người trợ giúp để sử dụng bên dưới function getFullName() { return firstName + " " + lastName; } - alert( "Hello, " + getFullName() ); - alert( "Bye, " + getFullName() ); + alert( "Xin chào, " + getFullName() ); + alert( "Tạm biệt, " + getFullName() ); } ``` -Here the *nested* function `getFullName()` is made for convenience. It can access the outer variables and so can return the full name. Nested functions are quite common in JavaScript. +Ở đây, hàm *lồng nhau* `getFullName()` được tạo ra để thuận tiện. Nó có thể truy cập các biến bên ngoài và do đó có thể trả về tên đầy đủ. Các hàm lồng nhau khá phổ biến trong JavaScript. -What's much more interesting, a nested function can be returned: either as a property of a new object or as a result by itself. It can then be used somewhere else. No matter where, it still has access to the same outer variables. +Điều thú vị hơn nhiều, một hàm lồng nhau có thể được trả về: dưới dạng thuộc tính của một đối tượng mới hoặc là kết quả của chính nó. Sau đó nó có thể được sử dụng ở một nơi khác. Bất kể ở đâu, nó vẫn có quyền truy cập vào các biến bên ngoài giống nhau. -Below, `makeCounter` creates the "counter" function that returns the next number on each invocation: +Bên dưới, `makeCounter` tạo hàm "bộ đếm" trả về số tiếp theo trên mỗi lệnh gọi: ```js run function makeCounter() { @@ -142,34 +142,34 @@ alert( counter() ); // 1 alert( counter() ); // 2 ``` -Despite being simple, slightly modified variants of that code have practical uses, for instance, as a [random number generator](https://en.wikipedia.org/wiki/Pseudorandom_number_generator) to generate random values for automated tests. +Mặc dù đơn giản, các biến thể được sửa đổi một chút của mã đó có những ứng dụng thực tế, chẳng hạn như [trình tạo số ngẫu nhiên](https://vi.wikipedia.org/wiki/B%E1%BB%99_sinh_s%E1%BB%91_gi%E1%BA%A3_ng%E1%BA%ABu_nhi%C3%AAn) để tạo các giá trị ngẫu nhiên cho các bài kiểm tra tự động. -How does this work? If we create multiple counters, will they be independent? What's going on with the variables here? +Cái này hoạt động ra sao? Nếu chúng ta tạo nhiều bộ đếm, chúng có độc lập không? Điều gì đang xảy ra với các biến ở đây? -Understanding such things is great for the overall knowledge of JavaScript and beneficial for more complex scenarios. So let's go a bit in-depth. +Hiểu những điều như vậy là rất tốt cho kiến thức tổng thể về JavaScript và có lợi cho các tình huống phức tạp hơn. Vì vậy, chúng ta hãy đi sâu hơn một chút. -## Lexical Environment +## Môi trường từ vựng -```warn header="Here be dragons!" -The in-depth technical explanation lies ahead. +```warn header="Đây là những con rồng!" +Phần giải thích kỹ thuật chuyên sâu nằm ở phía trước. -As far as I'd like to avoid low-level language details, any understanding without them would be lacking and incomplete, so get ready. +Theo như tôi muốn tránh các chi tiết ngôn ngữ cấp thấp, mọi hiểu biết nếu không có chúng sẽ thiếu sót và không đầy đủ, vì vậy hãy sẵn sàng. ``` -For clarity, the explanation is split into multiple steps. +Để rõ ràng, giải thích được chia thành nhiều bước. -### Step 1. Variables +### Bước 1. Biến -In JavaScript, every running function, code block `{...}`, and the script as a whole have an internal (hidden) associated object known as the *Lexical Environment*. +Trong JavaScript, mọi chức năng đang chạy, khối mã `{...}` và toàn bộ tập lệnh đều có một đối tượng liên quan (ẩn) bên trong được gọi là *Môi trường từ vựng*. -The Lexical Environment object consists of two parts: +Đối tượng Môi trường từ vựng bao gồm hai phần: -1. *Environment Record* -- an object that stores all local variables as its properties (and some other information like the value of `this`). -2. A reference to the *outer lexical environment*, the one associated with the outer code. +1. *Bản ghi Môi trường* -- một đối tượng lưu trữ tất cả các biến cục bộ làm thuộc tính của nó (và một số thông tin khác như giá trị của `this`). +2. Tham chiếu đến *Môi trường từ vựng bên ngoài*, môi trường được liên kết với mã bên ngoài. -**A "variable" is just a property of the special internal object, `Environment Record`. "To get or change a variable" means "to get or change a property of that object".** +**"Biến" chỉ là thuộc tính của đối tượng bên trong đặc biệt, `Bản ghi Môi trường`. "Nhận hoặc thay đổi một biến" có nghĩa là "lấy hoặc thay đổi một thuộc tính của đối tượng đó".** -In this simple code without functions, there is only one Lexical Environment: +Trong mã đơn giản không có hàm này, chỉ có một Môi trường từ vựng: ![lexical environment](lexical-environment-global.svg) From 66128120d5ea0520bba92e35c8dc6487f1622594 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Sat, 11 Mar 2023 10:55:43 +0700 Subject: [PATCH 03/83] Update article.md --- .../03-closure/article.md | 86 +++++++++---------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/article.md b/1-js/06-advanced-functions/03-closure/article.md index 23894cd1d..a5855a8e1 100644 --- a/1-js/06-advanced-functions/03-closure/article.md +++ b/1-js/06-advanced-functions/03-closure/article.md @@ -19,7 +19,7 @@ Trong JavaScript, có 3 cách để khai báo một biến: `let`, `const` (các - `var` cũ có một số điểm khác biệt đáng chú ý, chúng sẽ được đề cập trong bài viết . ``` -## Khói mã +## Khối mã Nếu một biến được khai báo bên trong khối mã `{...}`, thì nó chỉ hiển thị bên trong khối đó. @@ -162,103 +162,103 @@ Theo như tôi muốn tránh các chi tiết ngôn ngữ cấp thấp, mọi hi Trong JavaScript, mọi chức năng đang chạy, khối mã `{...}` và toàn bộ tập lệnh đều có một đối tượng liên quan (ẩn) bên trong được gọi là *Môi trường từ vựng*. -Đối tượng Môi trường từ vựng bao gồm hai phần: +Đối tượng Môi trường Từ vựng bao gồm hai phần: 1. *Bản ghi Môi trường* -- một đối tượng lưu trữ tất cả các biến cục bộ làm thuộc tính của nó (và một số thông tin khác như giá trị của `this`). -2. Tham chiếu đến *Môi trường từ vựng bên ngoài*, môi trường được liên kết với mã bên ngoài. +2. Tham chiếu đến *Môi trường Từ vựng bên ngoài*, môi trường được liên kết với mã bên ngoài. **"Biến" chỉ là thuộc tính của đối tượng bên trong đặc biệt, `Bản ghi Môi trường`. "Nhận hoặc thay đổi một biến" có nghĩa là "lấy hoặc thay đổi một thuộc tính của đối tượng đó".** -Trong mã đơn giản không có hàm này, chỉ có một Môi trường từ vựng: +Trong mã đơn giản không có hàm này, chỉ có một Môi trường Từ vựng: ![lexical environment](lexical-environment-global.svg) -This is the so-called *global* Lexical Environment, associated with the whole script. +Đây được gọi là Môi trường Từ vựng *chung*, được liên kết với toàn bộ tập lệnh. -On the picture above, the rectangle means Environment Record (variable store) and the arrow means the outer reference. The global Lexical Environment has no outer reference, that's why the arrow points to `null`. +Trong hình trên, hình chữ nhật có nghĩa là Bản ghi Môi trường (lưu trữ biến) và mũi tên có nghĩa là tham chiếu bên ngoài. Môi trường Từ điển chung không có tham chiếu bên ngoài, đó là lý do tại sao mũi tên trỏ đến `null`. -As the code starts executing and goes on, the Lexical Environment changes. +Khi mã bắt đầu thực thi và tiếp tục, Môi trường Từ vựng sẽ thay đổi. -Here's a little bit longer code: +Đây là mã dài hơn một chút: ![lexical environment](closure-variable-phrase.svg) -Rectangles on the right-hand side demonstrate how the global Lexical Environment changes during the execution: +Các hình chữ nhật ở phía bên tay phải thể hiện cách Môi trường Từ vựng chung thay đổi trong quá trình thực thi: -1. When the script starts, the Lexical Environment is pre-populated with all declared variables. - - Initially, they are in the "Uninitialized" state. That's a special internal state, it means that the engine knows about the variable, but it cannot be referenced until it has been declared with `let`. It's almost the same as if the variable didn't exist. -2. Then `let phrase` definition appears. There's no assignment yet, so its value is `undefined`. We can use the variable from this point forward. -3. `phrase` is assigned a value. -4. `phrase` changes the value. +1. Khi tập lệnh bắt đầu, Môi trường Từ vựng được điền trước với tất cả các biến đã khai báo. + - Ban đầu, chúng ở trạng thái "Uninitialized". Đó là một trạng thái bên trong đặc biệt, nó có nghĩa là engine biết về biến, nhưng nó không thể được tham chiếu cho đến khi nó được khai báo với `let`. Nó gần giống như thể biến không tồn tại. +2. Sau đó, định nghĩa `let phrase` xuất hiện. Chưa có nhiệm vụ nào, vì vậy giá trị của nó là `undefined`. Chúng ta có thể sử dụng biến từ thời điểm này trở đi. +3. `phrase` được gán một giá trị. +4. `phrase` thay đổi giá trị. -Everything looks simple for now, right? +Mọi thứ có vẻ đơn giản cho bây giờ, phải không? -- A variable is a property of a special internal object, associated with the currently executing block/function/script. -- Working with variables is actually working with the properties of that object. +- Biến là thuộc tính của một đối tượng bên trong đặc biệt, được liên kết với khối/hàm/tập lệnh hiện đang thực thi. +- Làm việc với biến thực chất là làm việc với thuộc tính của đối tượng đó. -```smart header="Lexical Environment is a specification object" -"Lexical Environment" is a specification object: it only exists "theoretically" in the [language specification](https://tc39.es/ecma262/#sec-lexical-environments) to describe how things work. We can't get this object in our code and manipulate it directly. +```smart header="Môi trường Từ vựng là một đối tượng thông số" +"Môi trường Từ vựng" là một đối tượng thông số: nó chỉ tồn tại "về mặt lý thuyết" trong [thông số kỹ thuật ngôn ngữ](https://tc39.es/ecma262/#sec-lexical-environments) để mô tả cách mọi thứ hoạt động. Chúng ta không thể lấy đối tượng này trong mã của mình và thao tác trực tiếp với nó. -JavaScript engines also may optimize it, discard variables that are unused to save memory and perform other internal tricks, as long as the visible behavior remains as described. +Các JavaScript engine cũng có thể tối ưu hóa nó, loại bỏ các biến không được sử dụng để tiết kiệm bộ nhớ và thực hiện các thủ thuật nội bộ khác, miễn là hành vi hiển thị vẫn như mô tả. ``` -### Step 2. Function Declarations +### Bước 2. Khai báo hàm -A function is also a value, like a variable. +Một hàm cũng là một giá trị, giống như một biến. -**The difference is that a Function Declaration is instantly fully initialized.** +**Sự khác biệt là một Khai báo hàm được khởi tạo đầy đủ ngay lập tức.** -When a Lexical Environment is created, a Function Declaration immediately becomes a ready-to-use function (unlike `let`, that is unusable till the declaration). +Khi một Môi trường Từ vựng được tạo, một Khai báo hàm ngay lập tức trở thành một hàm sẵn sàng sử dụng (không giống như `let`, không thể sử dụng được cho đến khi khai báo). -That's why we can use a function, declared as Function Declaration, even before the declaration itself. +Đó là lý do tại sao chúng ta có thể sử dụng một hàm, được khai báo là Khai báo hàm, ngay cả trước khi chính khai báo đó. -For example, here's the initial state of the global Lexical Environment when we add a function: +Ví dụ: đây là trạng thái ban đầu của Môi trường Từ vựng chung khi chúng ta thêm một hàm: ![](closure-function-declaration.svg) -Naturally, this behavior only applies to Function Declarations, not Function Expressions where we assign a function to a variable, such as `let say = function(name)...`. +Đương nhiên, hành vi này chỉ áp dụng cho Khai báo hàm, không áp dụng cho Biểu thức hàm trong đó chúng ta gán một hàm cho một biến, chẳng hạn như `hãy nói = hàm(tên)...`. -### Step 3. Inner and outer Lexical Environment +### Bước 3. Môi trường Từ vựng bên trong và bên ngoài -When a function runs, at the beginning of the call, a new Lexical Environment is created automatically to store local variables and parameters of the call. +Khi một hàm chạy, khi bắt đầu cuộc gọi, một Môi trường Từ vựng mới được tạo tự động để lưu trữ các biến cục bộ và tham số của cuộc gọi. -For instance, for `say("John")`, it looks like this (the execution is at the line, labelled with an arrow): +Chẳng hạn, đối với `say("John")`, nó trông như thế này (việc thực thi nằm ở dòng, được đánh dấu bằng một mũi tên): ![](lexical-environment-simple.svg) -During the function call we have two Lexical Environments: the inner one (for the function call) and the outer one (global): +Trong khi gọi hàm, chúng ta có hai Môi trường Từ vựng: môi trường bên trong (đối với lệnh gọi hàm) và môi trường bên ngoài (chung): -- The inner Lexical Environment corresponds to the current execution of `say`. It has a single property: `name`, the function argument. We called `say("John")`, so the value of the `name` is `"John"`. -- The outer Lexical Environment is the global Lexical Environment. It has the `phrase` variable and the function itself. +- Môi trường Từ vựng bên trong tương ứng với việc thực thi `say` hiện tại. Nó có một thuộc tính duy nhất: `name`, đối số của hàm. Chúng ta đã gọi `say("John")`, vì vậy giá trị của `name` là `"John"`. +- Môi trường Từ vựng bên ngoài là Môi trường Từ vựng chung. Nó có biến `phrase` và chính hàm đó. -The inner Lexical Environment has a reference to the `outer` one. +Môi trường Từ vựng bên trong có tham chiếu đến môi trường `bên ngoài`. -**When the code wants to access a variable -- the inner Lexical Environment is searched first, then the outer one, then the more outer one and so on until the global one.** +**Khi mã muốn truy cập một biến -- Môi trường Từ vựng bên trong được tìm kiếm trước, sau đó đến môi trường bên ngoài, rồi đến môi trường bên ngoài hơn, v.v. cho đến môi trường chung.** -If a variable is not found anywhere, that's an error in strict mode (without `use strict`, an assignment to a non-existing variable creates a new global variable, for compatibility with old code). +Nếu không tìm thấy biến ở bất kỳ đâu, thì đó là lỗi trong chế độ nghiêm ngặt (không có `usestrict`, việc gán cho một biến không tồn tại sẽ tạo ra một biến chung mới, để tương thích với mã cũ). -In this example the search proceeds as follows: +Trong ví dụ này, quá trình tìm kiếm diễn ra như sau: -- For the `name` variable, the `alert` inside `say` finds it immediately in the inner Lexical Environment. -- When it wants to access `phrase`, then there is no `phrase` locally, so it follows the reference to the outer Lexical Environment and finds it there. +- Đối với biến `name`, `alert` bên trong `say` tìm thấy nó ngay lập tức trong Môi trường Từ vựng bên trong. +- Khi nó muốn truy cập `phrase`, thì không có `phrase` cục bộ, vì vậy nó sẽ theo tham chiếu đến Môi trường Từ vựng bên ngoài và tìm thấy nó ở đó. ![lexical environment lookup](lexical-environment-simple-lookup.svg) -### Step 4. Returning a function +### Bước 4. Trả về một chức năng -Let's return to the `makeCounter` example. +Hãy quay lại ví dụ `makeCounter`. ```js function makeCounter() { From ef2e6354e197f57705c5b243955afbcf5d79c00b Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Wed, 15 Mar 2023 07:43:09 +0700 Subject: [PATCH 04/83] Update article.md --- .../03-closure/article.md | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/article.md b/1-js/06-advanced-functions/03-closure/article.md index a5855a8e1..2385b1c2e 100644 --- a/1-js/06-advanced-functions/03-closure/article.md +++ b/1-js/06-advanced-functions/03-closure/article.md @@ -160,7 +160,7 @@ Theo như tôi muốn tránh các chi tiết ngôn ngữ cấp thấp, mọi hi ### Bước 1. Biến -Trong JavaScript, mọi chức năng đang chạy, khối mã `{...}` và toàn bộ tập lệnh đều có một đối tượng liên quan (ẩn) bên trong được gọi là *Môi trường từ vựng*. +Trong JavaScript, mọi hàm đang chạy, khối mã `{...}` và toàn bộ tập lệnh đều có một đối tượng liên quan (ẩn) bên trong được gọi là *Môi trường Từ vựng*. Đối tượng Môi trường Từ vựng bao gồm hai phần: @@ -186,7 +186,7 @@ Khi mã bắt đầu thực thi và tiếp tục, Môi trường Từ vựng s Các hình chữ nhật ở phía bên tay phải thể hiện cách Môi trường Từ vựng chung thay đổi trong quá trình thực thi: 1. Khi tập lệnh bắt đầu, Môi trường Từ vựng được điền trước với tất cả các biến đã khai báo. - - Ban đầu, chúng ở trạng thái "Uninitialized". Đó là một trạng thái bên trong đặc biệt, nó có nghĩa là engine biết về biến, nhưng nó không thể được tham chiếu cho đến khi nó được khai báo với `let`. Nó gần giống như thể biến không tồn tại. + - Ban đầu, chúng ở trạng thái "Chưa khởi tạo". Đó là một trạng thái bên trong đặc biệt, nó có nghĩa là engine biết về biến, nhưng nó không thể được tham chiếu cho đến khi nó được khai báo với `let`. Nó gần giống như thể biến không tồn tại. 2. Sau đó, định nghĩa `let phrase` xuất hiện. Chưa có nhiệm vụ nào, vì vậy giá trị của nó là `undefined`. Chúng ta có thể sử dụng biến từ thời điểm này trở đi. 3. `phrase` được gán một giá trị. 4. `phrase` thay đổi giá trị. @@ -256,7 +256,7 @@ Trong ví dụ này, quá trình tìm kiếm diễn ra như sau: ![lexical environment lookup](lexical-environment-simple-lookup.svg) -### Bước 4. Trả về một chức năng +### Bước 4. Trả về một hàm Hãy quay lại ví dụ `makeCounter`. @@ -272,42 +272,42 @@ function makeCounter() { let counter = makeCounter(); ``` -At the beginning of each `makeCounter()` call, a new Lexical Environment object is created, to store variables for this `makeCounter` run. +Khi bắt đầu mỗi lệnh gọi `makeCounter()`, một đối tượng Môi trường Từ vựng mới được tạo để lưu trữ các biến cho lần chạy `makeCounter` này. -So we have two nested Lexical Environments, just like in the example above: +Vì vậy, chúng ta có hai Môi trường Từ vựng lồng nhau, giống như trong ví dụ trên: ![](closure-makecounter.svg) -What's different is that, during the execution of `makeCounter()`, a tiny nested function is created of only one line: `return count++`. We don't run it yet, only create. +Điều khác biệt là, trong quá trình thực thi `makeCounter()`, một hàm nhỏ lồng nhau được tạo chỉ từ một dòng: `return count++`. Chúng ta chưa chạy nó, chỉ tạo. -All functions remember the Lexical Environment in which they were made. Technically, there's no magic here: all functions have the hidden property named `[[Environment]]`, that keeps the reference to the Lexical Environment where the function was created: +Tất cả các hàm ghi nhớ Môi trường Từ vựng mà chúng được tạo ra. Về mặt kỹ thuật, không có phép thuật nào ở đây: tất cả các hàm đều có thuộc tính ẩn có tên `[[Môi trường]]`, giữ tham chiếu đến Môi trường Từ vựng nơi hàm được tạo: ![](closure-makecounter-environment.svg) -So, `counter.[[Environment]]` has the reference to `{count: 0}` Lexical Environment. That's how the function remembers where it was created, no matter where it's called. The `[[Environment]]` reference is set once and forever at function creation time. +Vì vậy, `counter.[[Environment]]` có tham chiếu đến `{count: 0}` Môi trường Từ vựng. Đó là cách hàm ghi nhớ nơi nó được tạo, bất kể nó được gọi ở đâu. Tham chiếu `[[Môi trường]]` được đặt một lần và mãi mãi tại thời điểm tạo hàm. -Later, when `counter()` is called, a new Lexical Environment is created for the call, and its outer Lexical Environment reference is taken from `counter.[[Environment]]`: +Sau đó, khi `counter()` được gọi, một Môi trường Từ vựng mới được tạo cho lệnh gọi và tham chiếu Môi trường từ vựng bên ngoài của nó được lấy từ `bộ đếm.[[Môi trường]]`: ![](closure-makecounter-nested-call.svg) -Now when the code inside `counter()` looks for `count` variable, it first searches its own Lexical Environment (empty, as there are no local variables there), then the Lexical Environment of the outer `makeCounter()` call, where it finds and changes it. +Bây giờ, khi mã bên trong `counter()` tìm kiếm biến `count`, trước tiên, nó tìm kiếm Môi trường Từ vựng của chính nó (trống, vì không có biến cục bộ nào ở đó), sau đó là Môi trường Từ vựng của lệnh gọi `makeCounter()` bên ngoài, nơi nó tìm thấy và thay đổi nó. -**A variable is updated in the Lexical Environment where it lives.** +**Một biến được cập nhật trong Môi trường Từ vựng nơi nó tồn tại.** -Here's the state after the execution: +Đây là trạng thái sau khi thực hiện: ![](closure-makecounter-nested-call-2.svg) -If we call `counter()` multiple times, the `count` variable will be increased to `2`, `3` and so on, at the same place. +Nếu chúng ta gọi `counter()` nhiều lần, biến `count` sẽ được tăng lên thành `2`, `3`, v.v., tại cùng một vị trí. -```smart header="Closure" -There is a general programming term "closure", that developers generally should know. +```smart header="Bao đóng" +Có một thuật ngữ lập trình chung là "bao đóng" mà các nhà phát triển thường nên biết. -A [closure](https://en.wikipedia.org/wiki/Closure_(computer_programming)) is a function that remembers its outer variables and can access them. In some languages, that's not possible, or a function should be written in a special way to make it happen. But as explained above, in JavaScript, all functions are naturally closures (there is only one exception, to be covered in ). +[Bao đóng](https://vi.wikipedia.org/wiki/Bao_%C4%91%C3%B3ng_(l%E1%BA%ADp_tr%C3%ACnh_m%C3%A1y_t%C3%ADnh)) là một hàm ghi nhớ các biến bên ngoài của nó và có thể truy cập chúng. Trong một số ngôn ngữ, điều đó là không thể, hoặc một hàm phải được viết theo một cách đặc biệt để làm cho nó xảy ra. Nhưng như đã giải thích ở trên, trong JavaScript, tất cả các hàm đều là các hàm đóng một cách tự nhiên (chỉ có một ngoại lệ, được đề cập trong ). -That is: they automatically remember where they were created using a hidden `[[Environment]]` property, and then their code can access outer variables. +Đó là: chúng tự động ghi nhớ nơi chúng được tạo bằng thuộc tính `[[Môi trường]]` ẩn, và sau đó mã của chúng có thể truy cập các biến bên ngoài. -When on an interview, a frontend developer gets a question about "what's a closure?", a valid answer would be a definition of the closure and an explanation that all functions in JavaScript are closures, and maybe a few more words about technical details: the `[[Environment]]` property and how Lexical Environments work. +Khi tham gia một cuộc phỏng vấn, một nhà phát triển giao diện người dùng nhận được câu hỏi về "bao đóng là gì?", một câu trả lời hợp lệ sẽ là định nghĩa về bao đóng và giải thích rằng tất cả các hàm trong JavaScript đều là đóng và có thể thêm một vài từ về chi tiết kỹ thuật: thuộc tính `[[Môi trường]]` và cách thức hoạt động của Môi trường Từ vựng. ``` ## Garbage collection From e43b1f7840ad3dca4eadb95cd717f52812a56a4d Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Wed, 15 Mar 2023 07:55:17 +0700 Subject: [PATCH 05/83] Update article.md --- .../03-closure/article.md | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/article.md b/1-js/06-advanced-functions/03-closure/article.md index 2385b1c2e..73ea9861e 100644 --- a/1-js/06-advanced-functions/03-closure/article.md +++ b/1-js/06-advanced-functions/03-closure/article.md @@ -1,5 +1,5 @@ -# Phạm vi biến, đóng kín +# Phạm vi biến, bao đóng JavaScript là một ngôn ngữ rất hướng hàm. Nó cho chúng ta rất nhiều tự do. Một hàm có thể được tạo bất cứ lúc nào, được chuyển dưới dạng đối số cho một hàm khác và sau đó được gọi từ một vị trí mã hoàn toàn khác sau đó. @@ -148,7 +148,7 @@ Cái này hoạt động ra sao? Nếu chúng ta tạo nhiều bộ đếm, chú Hiểu những điều như vậy là rất tốt cho kiến thức tổng thể về JavaScript và có lợi cho các tình huống phức tạp hơn. Vì vậy, chúng ta hãy đi sâu hơn một chút. -## Môi trường từ vựng +## Môi trường Từ vựng ```warn header="Đây là những con rồng!" Phần giải thích kỹ thuật chuyên sâu nằm ở phía trước. @@ -175,7 +175,7 @@ Trong mã đơn giản không có hàm này, chỉ có một Môi trường Từ Đây được gọi là Môi trường Từ vựng *chung*, được liên kết với toàn bộ tập lệnh. -Trong hình trên, hình chữ nhật có nghĩa là Bản ghi Môi trường (lưu trữ biến) và mũi tên có nghĩa là tham chiếu bên ngoài. Môi trường Từ điển chung không có tham chiếu bên ngoài, đó là lý do tại sao mũi tên trỏ đến `null`. +Trong hình trên, hình chữ nhật có nghĩa là Bản ghi Môi trường (lưu trữ biến) và mũi tên có nghĩa là tham chiếu bên ngoài. Môi trường Từ vựng chung không có tham chiếu bên ngoài, đó là lý do tại sao mũi tên trỏ đến `null`. Khi mã bắt đầu thực thi và tiếp tục, Môi trường Từ vựng sẽ thay đổi. @@ -286,7 +286,7 @@ Tất cả các hàm ghi nhớ Môi trường Từ vựng mà chúng được t Vì vậy, `counter.[[Environment]]` có tham chiếu đến `{count: 0}` Môi trường Từ vựng. Đó là cách hàm ghi nhớ nơi nó được tạo, bất kể nó được gọi ở đâu. Tham chiếu `[[Môi trường]]` được đặt một lần và mãi mãi tại thời điểm tạo hàm. -Sau đó, khi `counter()` được gọi, một Môi trường Từ vựng mới được tạo cho lệnh gọi và tham chiếu Môi trường từ vựng bên ngoài của nó được lấy từ `bộ đếm.[[Môi trường]]`: +Sau đó, khi `counter()` được gọi, một Môi trường Từ vựng mới được tạo cho lệnh gọi và tham chiếu Môi trường từ vựng bên ngoài của nó được lấy từ `bộ đếm.[[Environment]]`: ![](closure-makecounter-nested-call.svg) @@ -310,15 +310,15 @@ Có một thuật ngữ lập trình chung là "bao đóng" mà các nhà phát Khi tham gia một cuộc phỏng vấn, một nhà phát triển giao diện người dùng nhận được câu hỏi về "bao đóng là gì?", một câu trả lời hợp lệ sẽ là định nghĩa về bao đóng và giải thích rằng tất cả các hàm trong JavaScript đều là đóng và có thể thêm một vài từ về chi tiết kỹ thuật: thuộc tính `[[Môi trường]]` và cách thức hoạt động của Môi trường Từ vựng. ``` -## Garbage collection +## Thu gom rác -Usually, a Lexical Environment is removed from memory with all the variables after the function call finishes. That's because there are no references to it. As any JavaScript object, it's only kept in memory while it's reachable. +Thông thường, một Môi trường Từ vựng sẽ bị xóa khỏi bộ nhớ cùng với tất cả các biến sau khi lệnh gọi hàm kết thúc. Đó là bởi vì không có tham chiếu cho nó. Giống như bất kỳ đối tượng JavaScript nào, nó chỉ được lưu trong bộ nhớ khi có thể truy cập được. -However, if there's a nested function that is still reachable after the end of a function, then it has `[[Environment]]` property that references the lexical environment. +Tuy nhiên, nếu có một hàm lồng nhau vẫn có thể truy cập được sau khi kết thúc hàm, thì hàm đó có thuộc tính `[[Environment]]` tham chiếu Môi trường Từ vựng. -In that case the Lexical Environment is still reachable even after the completion of the function, so it stays alive. +Trong trường hợp đó, Môi trường Từ vựng vẫn có thể truy cập được ngay cả sau khi hoàn thành hàm, vì vậy nó vẫn tồn tại. -For example: +Ví dụ: ```js function f() { @@ -329,11 +329,11 @@ function f() { } } -let g = f(); // g.[[Environment]] stores a reference to the Lexical Environment -// of the corresponding f() call +let g = f(); // g.[[Environment]] lưu trữ một tham chiếu đến Môi trường Từ vựng +// của f() call tương ứng ``` -Please note that if `f()` is called many times, and resulting functions are saved, then all corresponding Lexical Environment objects will also be retained in memory. In the code below, all 3 of them: +Hãy lưu ý rằng nếu `f()` được gọi nhiều lần và các hàm kết quả được lưu, thì tất cả các đối tượng Môi trường Từ vựng tương ứng cũng sẽ được giữ lại trong bộ nhớ. Trong đoạn mã dưới đây, cả 3 cái trong số chúng: ```js function f() { @@ -342,14 +342,14 @@ function f() { return function() { alert(value); }; } -// 3 functions in array, every one of them links to Lexical Environment -// from the corresponding f() run +// 3 hàm trong array, mỗi hàm đều liên kết với Môi trường Từ vựng +// từ f() run tương ứng let arr = [f(), f(), f()]; ``` -A Lexical Environment object dies when it becomes unreachable (just like any other object). In other words, it exists only while there's at least one nested function referencing it. +Một đối tượng Môi trường Từ vựng sẽ chết khi không thể truy cập được (giống như bất kỳ đối tượng nào khác). Nói cách khác, nó chỉ tồn tại khi có ít nhất một hàm lồng nhau tham chiếu đến nó. -In the code below, after the nested function is removed, its enclosing Lexical Environment (and hence the `value`) is cleaned from memory: +Trong mã bên dưới, sau khi hàm lồng nhau bị xóa, Môi trường Từ vựng kèm theo của nó (và do đó, `value`) sẽ bị xóa khỏi bộ nhớ: ```js function f() { @@ -360,29 +360,29 @@ function f() { } } -let g = f(); // while g function exists, the value stays in memory +let g = f(); // trong khi hàm g tồn tại, giá trị vẫn nằm trong bộ nhớ -g = null; // ...and now the memory is cleaned up +g = null; // ...và bây giờ bộ nhớ đã được dọn sạch ``` -### Real-life optimizations +### Tối ưu hóa thực tế -As we've seen, in theory while a function is alive, all outer variables are also retained. +Như chúng ta đã thấy, theo lý thuyết, khi một hàm còn hoạt động, tất cả các biến bên ngoài cũng được giữ lại. -But in practice, JavaScript engines try to optimize that. They analyze variable usage and if it's obvious from the code that an outer variable is not used -- it is removed. +Nhưng trên thực tế, các JavaScript engine cố gắng tối ưu hóa điều đó. Họ phân tích việc sử dụng biến và nếu mã cho thấy rõ ràng rằng biến bên ngoài không được sử dụng -- biến đó sẽ bị xóa. -**An important side effect in V8 (Chrome, Edge, Opera) is that such variable will become unavailable in debugging.** +**Một tác dụng phụ quan trọng trong V8 (Chrome, Edge, Opera) là biến đó sẽ không khả dụng trong quá trình gỡ lỗi.** -Try running the example below in Chrome with the Developer Tools open. +Hãy thử chạy ví dụ bên dưới trong Chrome khi mở Công cụ dành cho nhà phát triển (console). -When it pauses, in the console type `alert(value)`. +Khi nó tạm dừng, trong bảng điều khiển hãy nhập `alert(value)`. ```js run function f() { let value = Math.random(); function g() { - debugger; // in console: type alert(value); No such variable! + debugger; // trong bảng điều khiển: nhập alert (value); Không có biến như vậy! } return g; @@ -392,18 +392,18 @@ let g = f(); g(); ``` -As you could see -- there is no such variable! In theory, it should be accessible, but the engine optimized it out. +Như bạn có thể thấy -- không có biến như vậy! Về lý thuyết, nó có thể truy cập được, nhưng engine đã tối ưu hóa nó. -That may lead to funny (if not such time-consuming) debugging issues. One of them -- we can see a same-named outer variable instead of the expected one: +Điều đó có thể dẫn đến các vấn đề gỡ lỗi buồn cười (nếu không muốn nói là tốn thời gian). Một trong số chúng -- chúng ta có thể thấy một biến ngoài cùng tên thay vì biến như mong đợi: ```js run global -let value = "Surprise!"; +let value = "Bất ngờ chưa!"; function f() { - let value = "the closest value"; + let value = "giá trị gần nhất"; function g() { - debugger; // in console: type alert(value); Surprise! + debugger; // trong bảng điều khiển: nhập alert (value); Bất ngờ chưa! } return g; @@ -413,6 +413,6 @@ let g = f(); g(); ``` -This feature of V8 is good to know. If you are debugging with Chrome/Edge/Opera, sooner or later you will meet it. +Tính năng này của V8 là tốt để biết. Nếu bạn đang gỡ lỗi bằng Chrome/Edge/Opera, sớm muộn gì bạn cũng sẽ gặp nó. -That is not a bug in the debugger, but rather a special feature of V8. Perhaps it will be changed sometime. You can always check for it by running the examples on this page. +Đó không phải là một lỗi trong trình gỡ lỗi, mà là một tính năng đặc biệt của V8. Có lẽ nó sẽ được thay đổi đôi khi. Bạn luôn có thể kiểm tra nó bằng cách chạy các ví dụ trên trang này. From 4ea135d89f8dd1658df3089b2246d59dcd945b58 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Wed, 15 Mar 2023 09:10:33 +0700 Subject: [PATCH 06/83] Update closure-function-declaration.svg --- .../03-closure/closure-function-declaration.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg b/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg index 3ef787875..c76a45716 100644 --- a/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg +++ b/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg @@ -1 +1 @@ -outernullexecution startphrase: <uninitialized> say: function... \ No newline at end of file +bên ngoàinullbắt đầu thực hiệncụm từ: <uninitialized> nói: hàm... From 9bfddd416bed032f68ea686a80439edfc812f92e Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Wed, 15 Mar 2023 09:11:06 +0700 Subject: [PATCH 07/83] Update closure-function-declaration.svg --- .../03-closure/closure-function-declaration.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg b/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg index c76a45716..380a5c32c 100644 --- a/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg +++ b/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg @@ -1 +1 @@ -bên ngoàinullbắt đầu thực hiệncụm từ: <uninitialized> nói: hàm... +bên ngoàinullbắt đầu thực hiệncụm từ: <chưa khởi tạo> nói: hàm... From f7be4f0c17b02cf37562d369b512839038226675 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 21:30:31 +0700 Subject: [PATCH 08/83] Update article.md --- 1-js/06-advanced-functions/03-closure/article.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/article.md b/1-js/06-advanced-functions/03-closure/article.md index 73ea9861e..04fe70f31 100644 --- a/1-js/06-advanced-functions/03-closure/article.md +++ b/1-js/06-advanced-functions/03-closure/article.md @@ -29,9 +29,9 @@ Ví dụ: { // thực hiện một số công việc với các biến cục bộ không nên nhìn thấy bên ngoài - let message = "Xin chào"; // chỉ hiển thị trong khối này + let message = "Hello"; // chỉ hiển thị trong khối này - alert(message); // Xin chào + alert(message); // Hello } alert(message); // Lỗi: tin nhắn không xác định @@ -42,13 +42,13 @@ Chúng ta có thể sử dụng điều này để cô lập một đoạn mã t ```js run { // hiển thị tin nhắn - let message = "Xin chào"; + let message = "Hello"; alert(message); } { // hiển thị một tin nhắn khác - let message = "Tạm biệt"; + let message = "Bye"; alert(message); } ``` @@ -58,12 +58,12 @@ Hãy lưu ý, nếu không có các khối riêng biệt sẽ xảy ra lỗi, n ```js run // hiển thị tin nhắn -let message = "Xin chào"; +let message = "Hello"; alert(message); // hiển thị một tin nhắn khác *!* -let message = "Tạm biệt"; // Lỗi: biến đã được khai báo +let message = "Bye"; // Lỗi: biến đã được khai báo */!* alert(message); ``` @@ -73,9 +73,9 @@ alert(message); ```js run if (true) { - let phrase = "Xin chào!"; + let phrase = "Hello!"; - alert(phrase); // Xin chào! + alert(phrase); // Hello! } alert(phrase); // Lỗi, không có biến như vậy! From e1eaab5b1e5e71f790cfa890b77921df271d4387 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 21:32:27 +0700 Subject: [PATCH 09/83] Update closure-makecounter-environment.svg --- .../03-closure/closure-makecounter-environment.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-makecounter-environment.svg b/1-js/06-advanced-functions/03-closure/closure-makecounter-environment.svg index f78441712..e8189d647 100644 --- a/1-js/06-advanced-functions/03-closure/closure-makecounter-environment.svg +++ b/1-js/06-advanced-functions/03-closure/closure-makecounter-environment.svg @@ -1 +1 @@ -null[[Environment]]makeCounter: function counter: undefinedcount: 0outerouter \ No newline at end of file +null[[Môi trường]]makeCounter: function counter: undefinedđếm: 0bên ngoàibên ngoài From b20946b33ac0a1aa4aef0ae634ecd1ae197c48f6 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 21:33:59 +0700 Subject: [PATCH 10/83] Update closure-makecounter-environment.svg --- .../03-closure/closure-makecounter-environment.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-makecounter-environment.svg b/1-js/06-advanced-functions/03-closure/closure-makecounter-environment.svg index e8189d647..c18a77336 100644 --- a/1-js/06-advanced-functions/03-closure/closure-makecounter-environment.svg +++ b/1-js/06-advanced-functions/03-closure/closure-makecounter-environment.svg @@ -1 +1 @@ -null[[Môi trường]]makeCounter: function counter: undefinedđếm: 0bên ngoàibên ngoài +null[[Môi trường]]makeCounter: hàm counter: undefinedđếm: 0bên ngoàibên ngoài From c84df457688b08920c8bf50b945dd8b70a11b252 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 21:35:46 +0700 Subject: [PATCH 11/83] Update closure-makecounter-nested-call-2.svg --- .../03-closure/closure-makecounter-nested-call-2.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call-2.svg b/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call-2.svg index 3950a8faa..d9c3f3f19 100644 --- a/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call-2.svg +++ b/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call-2.svg @@ -1 +1 @@ -count: 1<empty>nullouterouteroutermakeCounter: function counter: functionmodified here \ No newline at end of file +đếm: 1<trống>nullbên ngoàiouterbên ngoàimakeCounter: hàm counter: hàmsửa đổi ở đây From dcafb7b1abc0767a1a22432cac695cb863dd538c Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 21:37:18 +0700 Subject: [PATCH 12/83] Update closure-makecounter-nested-call-2.svg --- .../03-closure/closure-makecounter-nested-call-2.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call-2.svg b/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call-2.svg index d9c3f3f19..6ff171b79 100644 --- a/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call-2.svg +++ b/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call-2.svg @@ -1 +1 @@ -đếm: 1<trống>nullbên ngoàiouterbên ngoàimakeCounter: hàm counter: hàmsửa đổi ở đây +đếm: 1<trống>nullbên ngoàibên ngoàibên ngoàimakeCounter: function counter: functionsửa đổi ở đây From b33c5eb3287a07360cc03b5af1b53b7cbd84d60b Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 21:38:04 +0700 Subject: [PATCH 13/83] Update closure-function-declaration.svg --- .../03-closure/closure-function-declaration.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg b/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg index 380a5c32c..10822e9e4 100644 --- a/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg +++ b/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg @@ -1 +1 @@ -bên ngoàinullbắt đầu thực hiệncụm từ: <chưa khởi tạo> nói: hàm... +bên ngoàinullbắt đầu thực hiệncụm từ: <chưa khởi tạo> say: function... From b6a548fc9ec8bbae502af24cc20896830b1c9527 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 21:38:47 +0700 Subject: [PATCH 14/83] Update closure-makecounter-environment.svg --- .../03-closure/closure-makecounter-environment.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-makecounter-environment.svg b/1-js/06-advanced-functions/03-closure/closure-makecounter-environment.svg index c18a77336..e8189d647 100644 --- a/1-js/06-advanced-functions/03-closure/closure-makecounter-environment.svg +++ b/1-js/06-advanced-functions/03-closure/closure-makecounter-environment.svg @@ -1 +1 @@ -null[[Môi trường]]makeCounter: hàm counter: undefinedđếm: 0bên ngoàibên ngoài +null[[Môi trường]]makeCounter: function counter: undefinedđếm: 0bên ngoàibên ngoài From 8a4eede8375983178671831d7cb0a01f7493d156 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 21:41:49 +0700 Subject: [PATCH 15/83] Update closure-makecounter-nested-call.svg --- .../03-closure/closure-makecounter-nested-call.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg b/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg index 24315bf21..163ff78e4 100644 --- a/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg +++ b/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg @@ -1 +1 @@ -count: 0<empty>nullouterouteroutermakeCounter: function counter: function \ No newline at end of file +đếm: 0<trống>nullbên ngoàibên ngoàibên ngoàimakeCounter: function counter: function From b63ae2cf0694c9b63f194f7a6f2c3b540f1d7ec9 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 21:42:52 +0700 Subject: [PATCH 16/83] Update closure-makecounter-nested-call.svg --- .../03-closure/closure-makecounter-nested-call.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg b/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg index 163ff78e4..8a31d5d8e 100644 --- a/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg +++ b/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg @@ -1 +1 @@ -đếm: 0<trống>nullbên ngoàibên ngoàibên ngoàimakeCounter: function counter: function +đếm: 0<trống>nullbên ngoàibên ngoàibên ngoàimakeCounter: function counter: function From 57be90e9242d97658310aab0f186e69efa5761ac Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 21:43:16 +0700 Subject: [PATCH 17/83] Update closure-makecounter-nested-call.svg --- .../03-closure/closure-makecounter-nested-call.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg b/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg index 8a31d5d8e..f02bf1a1a 100644 --- a/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg +++ b/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg @@ -1 +1 @@ -đếm: 0<trống>nullbên ngoàibên ngoàibên ngoàimakeCounter: function counter: function +đếm: 0<trống>nullbên ngoàibên ngoàibên ngoàimakeCounter: function counter: function From 714290e2715843c04b3a299df33ee1d6a4a75ce4 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 21:43:32 +0700 Subject: [PATCH 18/83] Update closure-makecounter-nested-call.svg --- .../03-closure/closure-makecounter-nested-call.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg b/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg index f02bf1a1a..32cb46959 100644 --- a/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg +++ b/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg @@ -1 +1 @@ -đếm: 0<trống>nullbên ngoàibên ngoàibên ngoàimakeCounter: function counter: function +đếm: 0<trống>nullbên ngoàibên ngoàibên ngoàimakeCounter: function counter: function From 929d822569d2256779f89f73ba636ba30b7494b4 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 21:44:11 +0700 Subject: [PATCH 19/83] Update closure-makecounter-nested-call.svg --- .../03-closure/closure-makecounter-nested-call.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg b/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg index 32cb46959..ce5af19ea 100644 --- a/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg +++ b/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg @@ -1 +1 @@ -đếm: 0<trống>nullbên ngoàibên ngoàibên ngoàimakeCounter: function counter: function +đếm: 0<trống>nullbên ngoàibên ngoàibên ngoàimakeCounter: function counter: function From 00f9f896afeed9b46bf549e161085a449e9e66b8 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 21:44:41 +0700 Subject: [PATCH 20/83] Update closure-makecounter-nested-call.svg --- .../03-closure/closure-makecounter-nested-call.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg b/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg index ce5af19ea..11a82c4bd 100644 --- a/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg +++ b/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg @@ -1 +1 @@ -đếm: 0<trống>nullbên ngoàibên ngoàibên ngoàimakeCounter: function counter: function +đếm: 0<trống>nullbên ngoàibên ngoàibên ngoàimakeCounter: function counter: function From e2345d6321964d74c136328c38182b5349887645 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 21:45:25 +0700 Subject: [PATCH 21/83] Update closure-makecounter-environment.svg --- .../03-closure/closure-makecounter-environment.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-makecounter-environment.svg b/1-js/06-advanced-functions/03-closure/closure-makecounter-environment.svg index e8189d647..59d14f177 100644 --- a/1-js/06-advanced-functions/03-closure/closure-makecounter-environment.svg +++ b/1-js/06-advanced-functions/03-closure/closure-makecounter-environment.svg @@ -1 +1 @@ -null[[Môi trường]]makeCounter: function counter: undefinedđếm: 0bên ngoàibên ngoài +null[[Môi trường]]makeCounter: function counter: undefinedđếm: 0bên ngoàibên ngoài From a7651b3a99bb254c091be7c2f020d0fa3c621fcb Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 21:46:05 +0700 Subject: [PATCH 22/83] Update closure-makecounter-nested-call-2.svg --- .../03-closure/closure-makecounter-nested-call-2.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call-2.svg b/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call-2.svg index 6ff171b79..a1013e213 100644 --- a/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call-2.svg +++ b/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call-2.svg @@ -1 +1 @@ -đếm: 1<trống>nullbên ngoàibên ngoàibên ngoàimakeCounter: function counter: functionsửa đổi ở đây +đếm: 1<trống>nullbên ngoàibên ngoàibên ngoàimakeCounter: function counter: functionsửa đổi ở đây From 942b855022ed9b80fb626bb38b4294e66fe6297f Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 21:46:33 +0700 Subject: [PATCH 23/83] Update closure-makecounter-nested-call-2.svg --- .../03-closure/closure-makecounter-nested-call-2.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call-2.svg b/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call-2.svg index a1013e213..2f6cbb5cc 100644 --- a/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call-2.svg +++ b/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call-2.svg @@ -1 +1 @@ -đếm: 1<trống>nullbên ngoàibên ngoàibên ngoàimakeCounter: function counter: functionsửa đổi ở đây +đếm: 1<trống>nullbên ngoàibên ngoàibên ngoàimakeCounter: function counter: functionsửa đổi ở đây From 091c5b43f3c615979bddc9fda29f36bfb75e7737 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 21:53:51 +0700 Subject: [PATCH 24/83] Update article.md --- .../03-closure/article.md | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/article.md b/1-js/06-advanced-functions/03-closure/article.md index 04fe70f31..fcf7bd5ac 100644 --- a/1-js/06-advanced-functions/03-closure/article.md +++ b/1-js/06-advanced-functions/03-closure/article.md @@ -148,7 +148,7 @@ Cái này hoạt động ra sao? Nếu chúng ta tạo nhiều bộ đếm, chú Hiểu những điều như vậy là rất tốt cho kiến thức tổng thể về JavaScript và có lợi cho các tình huống phức tạp hơn. Vì vậy, chúng ta hãy đi sâu hơn một chút. -## Môi trường Từ vựng +## Lexical Environment ```warn header="Đây là những con rồng!" Phần giải thích kỹ thuật chuyên sâu nằm ở phía trước. @@ -162,20 +162,20 @@ Theo như tôi muốn tránh các chi tiết ngôn ngữ cấp thấp, mọi hi Trong JavaScript, mọi hàm đang chạy, khối mã `{...}` và toàn bộ tập lệnh đều có một đối tượng liên quan (ẩn) bên trong được gọi là *Môi trường Từ vựng*. -Đối tượng Môi trường Từ vựng bao gồm hai phần: +Đối tượng Lexical Environment bao gồm hai phần: -1. *Bản ghi Môi trường* -- một đối tượng lưu trữ tất cả các biến cục bộ làm thuộc tính của nó (và một số thông tin khác như giá trị của `this`). -2. Tham chiếu đến *Môi trường Từ vựng bên ngoài*, môi trường được liên kết với mã bên ngoài. +1. *Environment Record* -- một đối tượng lưu trữ tất cả các biến cục bộ làm thuộc tính của nó (và một số thông tin khác như giá trị của `this`). +2. Tham chiếu đến *Lexical Environment bên ngoài*, environment được liên kết với mã bên ngoài. -**"Biến" chỉ là thuộc tính của đối tượng bên trong đặc biệt, `Bản ghi Môi trường`. "Nhận hoặc thay đổi một biến" có nghĩa là "lấy hoặc thay đổi một thuộc tính của đối tượng đó".** +**"Biến" chỉ là thuộc tính của đối tượng bên trong đặc biệt, `Environment Record`. "Nhận hoặc thay đổi một biến" có nghĩa là "lấy hoặc thay đổi một thuộc tính của đối tượng đó".** -Trong mã đơn giản không có hàm này, chỉ có một Môi trường Từ vựng: +Trong mã đơn giản không có hàm này, chỉ có một Lexical Environment: ![lexical environment](lexical-environment-global.svg) -Đây được gọi là Môi trường Từ vựng *chung*, được liên kết với toàn bộ tập lệnh. +Đây được gọi là Lexical Environment *chung*, được liên kết với toàn bộ tập lệnh. -Trong hình trên, hình chữ nhật có nghĩa là Bản ghi Môi trường (lưu trữ biến) và mũi tên có nghĩa là tham chiếu bên ngoài. Môi trường Từ vựng chung không có tham chiếu bên ngoài, đó là lý do tại sao mũi tên trỏ đến `null`. +Trong hình trên, hình chữ nhật có nghĩa là Environment Recordg (lưu trữ biến) và mũi tên có nghĩa là tham chiếu bên ngoài. Lexical Environment chung không có tham chiếu bên ngoài, đó là lý do tại sao mũi tên trỏ đến `null`. Khi mã bắt đầu thực thi và tiếp tục, Môi trường Từ vựng sẽ thay đổi. @@ -185,7 +185,7 @@ Khi mã bắt đầu thực thi và tiếp tục, Môi trường Từ vựng s Các hình chữ nhật ở phía bên tay phải thể hiện cách Môi trường Từ vựng chung thay đổi trong quá trình thực thi: -1. Khi tập lệnh bắt đầu, Môi trường Từ vựng được điền trước với tất cả các biến đã khai báo. +1. Khi tập lệnh bắt đầu, Lexical Environment được điền trước với tất cả các biến đã khai báo. - Ban đầu, chúng ở trạng thái "Chưa khởi tạo". Đó là một trạng thái bên trong đặc biệt, nó có nghĩa là engine biết về biến, nhưng nó không thể được tham chiếu cho đến khi nó được khai báo với `let`. Nó gần giống như thể biến không tồn tại. 2. Sau đó, định nghĩa `let phrase` xuất hiện. Chưa có nhiệm vụ nào, vì vậy giá trị của nó là `undefined`. Chúng ta có thể sử dụng biến từ thời điểm này trở đi. 3. `phrase` được gán một giá trị. @@ -196,8 +196,8 @@ Mọi thứ có vẻ đơn giản cho bây giờ, phải không? - Biến là thuộc tính của một đối tượng bên trong đặc biệt, được liên kết với khối/hàm/tập lệnh hiện đang thực thi. - Làm việc với biến thực chất là làm việc với thuộc tính của đối tượng đó. -```smart header="Môi trường Từ vựng là một đối tượng thông số" -"Môi trường Từ vựng" là một đối tượng thông số: nó chỉ tồn tại "về mặt lý thuyết" trong [thông số kỹ thuật ngôn ngữ](https://tc39.es/ecma262/#sec-lexical-environments) để mô tả cách mọi thứ hoạt động. Chúng ta không thể lấy đối tượng này trong mã của mình và thao tác trực tiếp với nó. +```smart header="Lexical Environment là một đối tượng thông số" +"Lexical Environment" là một đối tượng thông số: nó chỉ tồn tại "về mặt lý thuyết" trong [thông số kỹ thuật ngôn ngữ](https://tc39.es/ecma262/#sec-lexical-environments) để mô tả cách mọi thứ hoạt động. Chúng ta không thể lấy đối tượng này trong mã của mình và thao tác trực tiếp với nó. Các JavaScript engine cũng có thể tối ưu hóa nó, loại bỏ các biến không được sử dụng để tiết kiệm bộ nhớ và thực hiện các thủ thuật nội bộ khác, miễn là hành vi hiển thị vẫn như mô tả. ``` @@ -208,19 +208,19 @@ Một hàm cũng là một giá trị, giống như một biến. **Sự khác biệt là một Khai báo hàm được khởi tạo đầy đủ ngay lập tức.** -Khi một Môi trường Từ vựng được tạo, một Khai báo hàm ngay lập tức trở thành một hàm sẵn sàng sử dụng (không giống như `let`, không thể sử dụng được cho đến khi khai báo). +Khi một Lexical Environment được tạo, một Khai báo hàm ngay lập tức trở thành một hàm sẵn sàng sử dụng (không giống như `let`, không thể sử dụng được cho đến khi khai báo). Đó là lý do tại sao chúng ta có thể sử dụng một hàm, được khai báo là Khai báo hàm, ngay cả trước khi chính khai báo đó. -Ví dụ: đây là trạng thái ban đầu của Môi trường Từ vựng chung khi chúng ta thêm một hàm: +Ví dụ: đây là trạng thái ban đầu của Lexical Environment chung khi chúng ta thêm một hàm: ![](closure-function-declaration.svg) Đương nhiên, hành vi này chỉ áp dụng cho Khai báo hàm, không áp dụng cho Biểu thức hàm trong đó chúng ta gán một hàm cho một biến, chẳng hạn như `hãy nói = hàm(tên)...`. -### Bước 3. Môi trường Từ vựng bên trong và bên ngoài +### Bước 3. Lexical Environment bên trong và bên ngoài -Khi một hàm chạy, khi bắt đầu cuộc gọi, một Môi trường Từ vựng mới được tạo tự động để lưu trữ các biến cục bộ và tham số của cuộc gọi. +Khi một hàm chạy, khi bắt đầu cuộc gọi, một Lexical Environment mới được tạo tự động để lưu trữ các biến cục bộ và tham số của cuộc gọi. Chẳng hạn, đối với `say("John")`, nó trông như thế này (việc thực thi nằm ở dòng, được đánh dấu bằng một mũi tên): @@ -237,21 +237,21 @@ Chẳng hạn, đối với `say("John")`, nó trông như thế này (việc th ![](lexical-environment-simple.svg) -Trong khi gọi hàm, chúng ta có hai Môi trường Từ vựng: môi trường bên trong (đối với lệnh gọi hàm) và môi trường bên ngoài (chung): +Trong khi gọi hàm, chúng ta có hai Lexical Environment: environment bên trong (đối với lệnh gọi hàm) và environment bên ngoài (chung): -- Môi trường Từ vựng bên trong tương ứng với việc thực thi `say` hiện tại. Nó có một thuộc tính duy nhất: `name`, đối số của hàm. Chúng ta đã gọi `say("John")`, vì vậy giá trị của `name` là `"John"`. -- Môi trường Từ vựng bên ngoài là Môi trường Từ vựng chung. Nó có biến `phrase` và chính hàm đó. +- Lexical Environment bên trong tương ứng với việc thực thi `say` hiện tại. Nó có một thuộc tính duy nhất: `name`, đối số của hàm. Chúng ta đã gọi `say("John")`, vì vậy giá trị của `name` là `"John"`. +- Lexical Environment bên ngoài là Môi trường Từ vựng chung. Nó có biến `phrase` và chính hàm đó. -Môi trường Từ vựng bên trong có tham chiếu đến môi trường `bên ngoài`. +Lexical Environment bên trong có tham chiếu đến môi trường `bên ngoài`. -**Khi mã muốn truy cập một biến -- Môi trường Từ vựng bên trong được tìm kiếm trước, sau đó đến môi trường bên ngoài, rồi đến môi trường bên ngoài hơn, v.v. cho đến môi trường chung.** +**Khi mã muốn truy cập một biến -- Lexical Environment bên trong được tìm kiếm trước, sau đó đến environment bên ngoài, rồi đến environment bên ngoài hơn, v.v. cho đến môi trường chung.** Nếu không tìm thấy biến ở bất kỳ đâu, thì đó là lỗi trong chế độ nghiêm ngặt (không có `usestrict`, việc gán cho một biến không tồn tại sẽ tạo ra một biến chung mới, để tương thích với mã cũ). Trong ví dụ này, quá trình tìm kiếm diễn ra như sau: -- Đối với biến `name`, `alert` bên trong `say` tìm thấy nó ngay lập tức trong Môi trường Từ vựng bên trong. -- Khi nó muốn truy cập `phrase`, thì không có `phrase` cục bộ, vì vậy nó sẽ theo tham chiếu đến Môi trường Từ vựng bên ngoài và tìm thấy nó ở đó. +- Đối với biến `name`, `alert` bên trong `say` tìm thấy nó ngay lập tức trong Lexical Environment bên trong. +- Khi nó muốn truy cập `phrase`, thì không có `phrase` cục bộ, vì vậy nó sẽ theo tham chiếu đến Lexical Environment bên ngoài và tìm thấy nó ở đó. ![lexical environment lookup](lexical-environment-simple-lookup.svg) @@ -272,27 +272,27 @@ function makeCounter() { let counter = makeCounter(); ``` -Khi bắt đầu mỗi lệnh gọi `makeCounter()`, một đối tượng Môi trường Từ vựng mới được tạo để lưu trữ các biến cho lần chạy `makeCounter` này. +Khi bắt đầu mỗi lệnh gọi `makeCounter()`, một đối tượng Lexical Environment mới được tạo để lưu trữ các biến cho lần chạy `makeCounter` này. -Vì vậy, chúng ta có hai Môi trường Từ vựng lồng nhau, giống như trong ví dụ trên: +Vì vậy, chúng ta có hai Lexical Environment lồng nhau, giống như trong ví dụ trên: ![](closure-makecounter.svg) Điều khác biệt là, trong quá trình thực thi `makeCounter()`, một hàm nhỏ lồng nhau được tạo chỉ từ một dòng: `return count++`. Chúng ta chưa chạy nó, chỉ tạo. -Tất cả các hàm ghi nhớ Môi trường Từ vựng mà chúng được tạo ra. Về mặt kỹ thuật, không có phép thuật nào ở đây: tất cả các hàm đều có thuộc tính ẩn có tên `[[Môi trường]]`, giữ tham chiếu đến Môi trường Từ vựng nơi hàm được tạo: +Tất cả các hàm ghi nhớ Lexical Environment mà chúng được tạo ra. Về mặt kỹ thuật, không có phép thuật nào ở đây: tất cả các hàm đều có thuộc tính ẩn có tên `[[Môi trường]]`, giữ tham chiếu đến Lexical Environment nơi hàm được tạo: ![](closure-makecounter-environment.svg) -Vì vậy, `counter.[[Environment]]` có tham chiếu đến `{count: 0}` Môi trường Từ vựng. Đó là cách hàm ghi nhớ nơi nó được tạo, bất kể nó được gọi ở đâu. Tham chiếu `[[Môi trường]]` được đặt một lần và mãi mãi tại thời điểm tạo hàm. +Vì vậy, `counter.[[Environment]]` có tham chiếu đến `{count: 0}` Lexical Environment. Đó là cách hàm ghi nhớ nơi nó được tạo, bất kể nó được gọi ở đâu. Tham chiếu `[[Môi trường]]` được đặt một lần và mãi mãi tại thời điểm tạo hàm. -Sau đó, khi `counter()` được gọi, một Môi trường Từ vựng mới được tạo cho lệnh gọi và tham chiếu Môi trường từ vựng bên ngoài của nó được lấy từ `bộ đếm.[[Environment]]`: +Sau đó, khi `counter()` được gọi, một Lexical Environment mới được tạo cho lệnh gọi và tham chiếu Lexical Environment bên ngoài của nó được lấy từ `bộ đếm.[[Environment]]`: ![](closure-makecounter-nested-call.svg) -Bây giờ, khi mã bên trong `counter()` tìm kiếm biến `count`, trước tiên, nó tìm kiếm Môi trường Từ vựng của chính nó (trống, vì không có biến cục bộ nào ở đó), sau đó là Môi trường Từ vựng của lệnh gọi `makeCounter()` bên ngoài, nơi nó tìm thấy và thay đổi nó. +Bây giờ, khi mã bên trong `counter()` tìm kiếm biến `count`, trước tiên, nó tìm kiếm Lexical Environment của chính nó (trống, vì không có biến cục bộ nào ở đó), sau đó là Lexical Environment của lệnh gọi `makeCounter()` bên ngoài, nơi nó tìm thấy và thay đổi nó. -**Một biến được cập nhật trong Môi trường Từ vựng nơi nó tồn tại.** +**Một biến được cập nhật trong Lexical Environment nơi nó tồn tại.** Đây là trạng thái sau khi thực hiện: @@ -312,11 +312,11 @@ Khi tham gia một cuộc phỏng vấn, một nhà phát triển giao diện ng ## Thu gom rác -Thông thường, một Môi trường Từ vựng sẽ bị xóa khỏi bộ nhớ cùng với tất cả các biến sau khi lệnh gọi hàm kết thúc. Đó là bởi vì không có tham chiếu cho nó. Giống như bất kỳ đối tượng JavaScript nào, nó chỉ được lưu trong bộ nhớ khi có thể truy cập được. +Thông thường, một Lexical Environmentg sẽ bị xóa khỏi bộ nhớ cùng với tất cả các biến sau khi lệnh gọi hàm kết thúc. Đó là bởi vì không có tham chiếu cho nó. Giống như bất kỳ đối tượng JavaScript nào, nó chỉ được lưu trong bộ nhớ khi có thể truy cập được. -Tuy nhiên, nếu có một hàm lồng nhau vẫn có thể truy cập được sau khi kết thúc hàm, thì hàm đó có thuộc tính `[[Environment]]` tham chiếu Môi trường Từ vựng. +Tuy nhiên, nếu có một hàm lồng nhau vẫn có thể truy cập được sau khi kết thúc hàm, thì hàm đó có thuộc tính `[[Environment]]` tham chiếu Lexical Environment. -Trong trường hợp đó, Môi trường Từ vựng vẫn có thể truy cập được ngay cả sau khi hoàn thành hàm, vì vậy nó vẫn tồn tại. +Trong trường hợp đó, Lexical Environment vẫn có thể truy cập được ngay cả sau khi hoàn thành hàm, vì vậy nó vẫn tồn tại. Ví dụ: @@ -329,11 +329,11 @@ function f() { } } -let g = f(); // g.[[Environment]] lưu trữ một tham chiếu đến Môi trường Từ vựng +let g = f(); // g.[[Environment]] lưu trữ một tham chiếu đến Lexical Environment // của f() call tương ứng ``` -Hãy lưu ý rằng nếu `f()` được gọi nhiều lần và các hàm kết quả được lưu, thì tất cả các đối tượng Môi trường Từ vựng tương ứng cũng sẽ được giữ lại trong bộ nhớ. Trong đoạn mã dưới đây, cả 3 cái trong số chúng: +Hãy lưu ý rằng nếu `f()` được gọi nhiều lần và các hàm kết quả được lưu, thì tất cả các đối tượng Lexical Environment tương ứng cũng sẽ được giữ lại trong bộ nhớ. Trong đoạn mã dưới đây, cả 3 cái trong số chúng: ```js function f() { @@ -347,9 +347,9 @@ function f() { let arr = [f(), f(), f()]; ``` -Một đối tượng Môi trường Từ vựng sẽ chết khi không thể truy cập được (giống như bất kỳ đối tượng nào khác). Nói cách khác, nó chỉ tồn tại khi có ít nhất một hàm lồng nhau tham chiếu đến nó. +Một đối tượng Lexical Environment sẽ chết khi không thể truy cập được (giống như bất kỳ đối tượng nào khác). Nói cách khác, nó chỉ tồn tại khi có ít nhất một hàm lồng nhau tham chiếu đến nó. -Trong mã bên dưới, sau khi hàm lồng nhau bị xóa, Môi trường Từ vựng kèm theo của nó (và do đó, `value`) sẽ bị xóa khỏi bộ nhớ: +Trong mã bên dưới, sau khi hàm lồng nhau bị xóa, Lexical Environment kèm theo của nó (và do đó, `value`) sẽ bị xóa khỏi bộ nhớ: ```js function f() { From ae48d63384cc940e2eee0633ee6dcc7fac4f60a7 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 21:54:34 +0700 Subject: [PATCH 25/83] Update closure-function-declaration.svg --- .../03-closure/closure-function-declaration.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg b/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg index 10822e9e4..303564040 100644 --- a/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg +++ b/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg @@ -1 +1 @@ -bên ngoàinullbắt đầu thực hiệncụm từ: <chưa khởi tạo> say: function... +bên ngoàinullbắt đầu thực hiệnphrase: <chưa khởi tạo> say: function... From 937e6705ae154ee4989461e5887706faddf7c2e6 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 21:55:15 +0700 Subject: [PATCH 26/83] Update closure-function-declaration.svg --- .../03-closure/closure-function-declaration.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg b/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg index 303564040..13a00176c 100644 --- a/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg +++ b/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg @@ -1 +1 @@ -bên ngoàinullbắt đầu thực hiệnphrase: <chưa khởi tạo> say: function... +bên ngoàinullbắt đầu thực hiệnphrase: <chưa khởi tạo> say: hàm... From 3a56f9c1c064f6e5ab8c33738e761fc7e5e91a5f Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 21:56:05 +0700 Subject: [PATCH 27/83] Update closure-makecounter-environment.svg --- .../03-closure/closure-makecounter-environment.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-makecounter-environment.svg b/1-js/06-advanced-functions/03-closure/closure-makecounter-environment.svg index 59d14f177..737b16c8a 100644 --- a/1-js/06-advanced-functions/03-closure/closure-makecounter-environment.svg +++ b/1-js/06-advanced-functions/03-closure/closure-makecounter-environment.svg @@ -1 +1 @@ -null[[Môi trường]]makeCounter: function counter: undefinedđếm: 0bên ngoàibên ngoài +null[[Environment]]makeCounter: hàm counter: undefinedđếm: 0bên ngoàibên ngoài From 86d3653c7528901912e2dbba34666424cad05f22 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 21:56:36 +0700 Subject: [PATCH 28/83] Update closure-makecounter-nested-call-2.svg --- .../03-closure/closure-makecounter-nested-call-2.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call-2.svg b/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call-2.svg index 2f6cbb5cc..d0092ce0e 100644 --- a/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call-2.svg +++ b/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call-2.svg @@ -1 +1 @@ -đếm: 1<trống>nullbên ngoàibên ngoàibên ngoàimakeCounter: function counter: functionsửa đổi ở đây +đếm: 1<trống>nullbên ngoàibên ngoàibên ngoàimakeCounter: hàm counter: hàmsửa đổi ở đây From 1b3695fb73e27c2084ab697ba095fc8268a9c2ef Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 21:58:34 +0700 Subject: [PATCH 29/83] Update closure-makecounter-nested-call.svg --- .../03-closure/closure-makecounter-nested-call.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg b/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg index 11a82c4bd..c8b87dbf5 100644 --- a/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg +++ b/1-js/06-advanced-functions/03-closure/closure-makecounter-nested-call.svg @@ -1 +1 @@ -đếm: 0<trống>nullbên ngoàibên ngoàibên ngoàimakeCounter: function counter: function +đếm: 0<trống>nullbên ngoàibên ngoàibên ngoàimakeCounter: hàm counter: hàm From 4f7b3a63c5be2db6fd0458f2b05cfb337fbc1e62 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 22:00:07 +0700 Subject: [PATCH 30/83] Update closure-makecounter.svg --- 1-js/06-advanced-functions/03-closure/closure-makecounter.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-makecounter.svg b/1-js/06-advanced-functions/03-closure/closure-makecounter.svg index 2ca06455a..1c0412c07 100644 --- a/1-js/06-advanced-functions/03-closure/closure-makecounter.svg +++ b/1-js/06-advanced-functions/03-closure/closure-makecounter.svg @@ -1 +1 @@ -makeCounter: function counter: undefinedcount: 0nullglobal LexicalEnvironmentLexicalEnvironment of makeCounter() callouterouter \ No newline at end of file +makeCounter: hàm counter: undefinedđếm: 0nullLexical Environment chungLexical Environment của cuộc gọi makeCounter()bên ngoàibên ngoài From c7f8584bded2792b3bf3d388f198f2e52a60d694 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 22:01:37 +0700 Subject: [PATCH 31/83] Update closure-variable-phrase.svg --- .../03-closure/closure-variable-phrase.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-variable-phrase.svg b/1-js/06-advanced-functions/03-closure/closure-variable-phrase.svg index b9bb12fff..051224e5c 100644 --- a/1-js/06-advanced-functions/03-closure/closure-variable-phrase.svg +++ b/1-js/06-advanced-functions/03-closure/closure-variable-phrase.svg @@ -1 +1 @@ -phrase: "Bye"phrase: "Hello"phrase: undefinedphrase: <uninitialized>outernullexecution start \ No newline at end of file +phrase: "Bye"phrase: "Hello"phrase: undefinedphrase: <chưa khởi tạo>bên ngoàinullbắt đầu thực hiện From 2cb5bff34b7aac2d43cee1ba5d6e9b6e83bb66a2 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 22:02:41 +0700 Subject: [PATCH 32/83] Update lexenv-if.svg --- 1-js/06-advanced-functions/03-closure/lexenv-if.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/lexenv-if.svg b/1-js/06-advanced-functions/03-closure/lexenv-if.svg index 3d4d6d7cc..698569c4d 100644 --- a/1-js/06-advanced-functions/03-closure/lexenv-if.svg +++ b/1-js/06-advanced-functions/03-closure/lexenv-if.svg @@ -1 +1 @@ -phrase: "Hello"outerouternulluser: "John" \ No newline at end of file +phrase: "Hello"bên ngoàibên ngoàinulluser: "John" From 9ec38bb8ab6e83eadeea1f2a15b1ea285deb0ee2 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 22:03:11 +0700 Subject: [PATCH 33/83] Update lexenv-if.svg --- 1-js/06-advanced-functions/03-closure/lexenv-if.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/lexenv-if.svg b/1-js/06-advanced-functions/03-closure/lexenv-if.svg index 698569c4d..4cd767692 100644 --- a/1-js/06-advanced-functions/03-closure/lexenv-if.svg +++ b/1-js/06-advanced-functions/03-closure/lexenv-if.svg @@ -1 +1 @@ -phrase: "Hello"bên ngoàibên ngoàinulluser: "John" +phrase: "Hello"bên ngoàibên ngoàinulluser: "John" From 3c11ee17017d731ce14c65b2644a6ed17d2792f6 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 22:04:00 +0700 Subject: [PATCH 34/83] Update lexenv-nested-makecounter-1.svg --- .../03-closure/lexenv-nested-makecounter-1.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-1.svg b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-1.svg index f15e77a88..be0178bec 100644 --- a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-1.svg +++ b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-1.svg @@ -1 +1 @@ -makeCounter: function[[Environment]]outernull \ No newline at end of file +makeCounter: hàm[[Environment]]bên ngoàinull From 78ce0b6b945779225d950b8fd19cc5f876b6cebf Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 22:05:46 +0700 Subject: [PATCH 35/83] Update lexenv-nested-makecounter-2.svg --- .../03-closure/lexenv-nested-makecounter-2.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-2.svg b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-2.svg index f37488537..1a13ee8e1 100644 --- a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-2.svg +++ b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-2.svg @@ -1 +1 @@ -makeCounter: functioncounter: undefinedcount: 0outerouternullglobal LexicalEnvironmentLexicalEnvironment of makeCounter() call \ No newline at end of file +makeCounter: hàmcounter: undefinedđếm: 0bên ngoàibên ngoàinullLexical Environment chungLexical Environment của cuộc gọi makeCounter() From 0324e1370cb191a895a041a8b68a2520adbf0785 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Thu, 16 Mar 2023 22:06:49 +0700 Subject: [PATCH 36/83] Update lexenv-nested-makecounter-3.svg --- .../03-closure/lexenv-nested-makecounter-3.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-3.svg b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-3.svg index 54f1d97ba..0aab7fc8e 100644 --- a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-3.svg +++ b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-3.svg @@ -1 +1 @@ -makeCounter: functioncounter: undefinedcount: 0outerouternull[[Environment]] \ No newline at end of file +makeCounter: hàmcounter: undefinedđếm: 0outerbên ngoàinull[[Environment]] From f06eeccdaf5b0884a96178766476e4ef59e59bd3 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 20 Mar 2023 20:50:46 +0700 Subject: [PATCH 37/83] Update lexenv-nested-makecounter-4.svg --- .../03-closure/lexenv-nested-makecounter-4.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-4.svg b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-4.svg index fb60a785f..ddd7734e3 100644 --- a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-4.svg +++ b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-4.svg @@ -1 +1 @@ -makeCounter: functioncounter: functioncount: 0outerouternull[[Environment]] \ No newline at end of file +makeCounter: hàmcounter: hàmđếm: 0bên ngoàibên ngoàinull[[Environment]] From a434eda9908be6ac9f5459c13b1d33da34b99392 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Sun, 9 Apr 2023 12:19:25 +0700 Subject: [PATCH 38/83] Update lexenv-nested-makecounter-5.svg --- .../03-closure/lexenv-nested-makecounter-5.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-5.svg b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-5.svg index 79c440da7..d2e636276 100644 --- a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-5.svg +++ b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-5.svg @@ -1 +1 @@ -makeCounter: functioncounter: functioncount: 0<empty>outerouterouternull[[Environment]] \ No newline at end of file +makeCounter: hàmcounter: hàmcount: 0<trống>outerbên ngoàibên ngoàinull[[Environment]] From 8046ccf979647237b8643524c39c94fb83da95ed Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Sun, 9 Apr 2023 12:20:51 +0700 Subject: [PATCH 39/83] Update closure-makecounter-environment.svg --- .../03-closure/closure-makecounter-environment.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-makecounter-environment.svg b/1-js/06-advanced-functions/03-closure/closure-makecounter-environment.svg index 737b16c8a..c47d642f3 100644 --- a/1-js/06-advanced-functions/03-closure/closure-makecounter-environment.svg +++ b/1-js/06-advanced-functions/03-closure/closure-makecounter-environment.svg @@ -1 +1 @@ -null[[Environment]]makeCounter: hàm counter: undefinedđếm: 0bên ngoàibên ngoài +null[[Environment]]makeCounter: hàm counter: không xác địnhcount: 0bên ngoàibên ngoài From a0c22c35b0aab222315ca8fba7aad64c581a4963 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 22 May 2023 20:36:21 +0700 Subject: [PATCH 40/83] Update article.md --- 1-js/06-advanced-functions/03-closure/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/article.md b/1-js/06-advanced-functions/03-closure/article.md index fcf7bd5ac..100d4eb61 100644 --- a/1-js/06-advanced-functions/03-closure/article.md +++ b/1-js/06-advanced-functions/03-closure/article.md @@ -1,7 +1,7 @@ # Phạm vi biến, bao đóng -JavaScript là một ngôn ngữ rất hướng hàm. Nó cho chúng ta rất nhiều tự do. Một hàm có thể được tạo bất cứ lúc nào, được chuyển dưới dạng đối số cho một hàm khác và sau đó được gọi từ một vị trí mã hoàn toàn khác sau đó. +JavaScript là một ngôn ngữ rất hướng hàm. Nó cho chúng ta rất nhiều sự tự do. Một hàm có thể được tạo bất cứ lúc nào, được chuyển dưới dạng đối số cho một hàm khác và sau đó được gọi từ một vị trí mã hoàn toàn khác sau đó. Chúng ta đã biết rằng một hàm có thể truy cập các biến bên ngoài nó (các biến "bên ngoài"). From 35ebe022e860dbd5c62952212903620b24b504a9 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 22 May 2023 20:37:12 +0700 Subject: [PATCH 41/83] Update closure-function-declaration.svg --- .../03-closure/closure-function-declaration.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg b/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg index 13a00176c..aa4e4b262 100644 --- a/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg +++ b/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg @@ -1 +1 @@ -bên ngoàinullbắt đầu thực hiệnphrase: <chưa khởi tạo> say: hàm... +bên ngoàinullbắt đầu thực hiệnphrase: <chưa khởi tạo> say: hàm... From f163cc15b8bc7db8a4004591395deed30be2a1ec Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 22 May 2023 20:38:51 +0700 Subject: [PATCH 42/83] Update closure-function-declaration.svg --- .../03-closure/closure-function-declaration.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg b/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg index aa4e4b262..13a00176c 100644 --- a/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg +++ b/1-js/06-advanced-functions/03-closure/closure-function-declaration.svg @@ -1 +1 @@ -bên ngoàinullbắt đầu thực hiệnphrase: <chưa khởi tạo> say: hàm... +bên ngoàinullbắt đầu thực hiệnphrase: <chưa khởi tạo> say: hàm... From 2de5a79b1d659f8d7d437ba5f32e069fac718027 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 18:05:04 +0700 Subject: [PATCH 43/83] Update lexenv-nested-makecounter-6.svg --- .../03-closure/lexenv-nested-makecounter-6.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-6.svg b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-6.svg index 06d5b5060..593444b77 100644 --- a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-6.svg +++ b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-6.svg @@ -1 +1 @@ -makeCounter: functioncounter: functioncount: 1outerouternull[[Environment]]modified here \ No newline at end of file +makeCounter: hàmcounter: hàmcount: 1bên ngoàibên ngoàinull[[Environment]]chỉnh sửa ở đây From 2dc9df34ca157a276ed4f7de385d849fd7794640 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 18:06:59 +0700 Subject: [PATCH 44/83] Update lexenv-nested-makecounter-6.svg --- .../03-closure/lexenv-nested-makecounter-6.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-6.svg b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-6.svg index 593444b77..87046c73b 100644 --- a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-6.svg +++ b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-6.svg @@ -1 +1 @@ -makeCounter: hàmcounter: hàmcount: 1bên ngoàibên ngoàinull[[Environment]]chỉnh sửa ở đây +makeCounter: hàmcounter: hàmcount: 1bên ngoàibên ngoàinull[[Environment]]chỉnh sửa ở đây From da0796037f457b56589cd39a98f36c3e0dfacb1f Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 18:12:37 +0700 Subject: [PATCH 45/83] Update lexical-environment-global-2.svg --- .../03-closure/lexical-environment-global-2.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/lexical-environment-global-2.svg b/1-js/06-advanced-functions/03-closure/lexical-environment-global-2.svg index b6e576f0c..b6df53605 100644 --- a/1-js/06-advanced-functions/03-closure/lexical-environment-global-2.svg +++ b/1-js/06-advanced-functions/03-closure/lexical-environment-global-2.svg @@ -1 +1 @@ -phrase: "Bye"phrase: "Hello"phrase: undefined<empty>outernullexecution start \ No newline at end of file +phrase: "Bye"phrase: "Hello"phrase: undefined<trống>bên ngoàinullbắt đầu thực hiện From 933bdf287f6f9b305d06fba0ba2c28761a023d46 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 18:13:50 +0700 Subject: [PATCH 46/83] Update lexical-environment-global-3.svg --- .../03-closure/lexical-environment-global-3.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/lexical-environment-global-3.svg b/1-js/06-advanced-functions/03-closure/lexical-environment-global-3.svg index 1942a7e37..da1c5b86b 100644 --- a/1-js/06-advanced-functions/03-closure/lexical-environment-global-3.svg +++ b/1-js/06-advanced-functions/03-closure/lexical-environment-global-3.svg @@ -1 +1 @@ -say: function phrase: "Hello"say: functionouternullexecution start \ No newline at end of file +say: hàm phrase: "Hello"say: hàmbên ngoàinullbắt đầu thực hiện From 46803768c41484575668b105e39248da353ffbbd Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 18:14:39 +0700 Subject: [PATCH 47/83] Update lexical-environment-global.svg --- .../03-closure/lexical-environment-global.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/lexical-environment-global.svg b/1-js/06-advanced-functions/03-closure/lexical-environment-global.svg index 7bddc2230..63ae2fcae 100644 --- a/1-js/06-advanced-functions/03-closure/lexical-environment-global.svg +++ b/1-js/06-advanced-functions/03-closure/lexical-environment-global.svg @@ -1 +1 @@ -phrase: "Hello"outernullLexical Environment \ No newline at end of file +phrase: "Hello"bên ngoàinullLexical Environment From 08fb0e6d58513420e3e08128d63c07ad739ef8db Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 18:16:28 +0700 Subject: [PATCH 48/83] Update lexical-environment-simple-lookup.svg --- .../03-closure/lexical-environment-simple-lookup.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/lexical-environment-simple-lookup.svg b/1-js/06-advanced-functions/03-closure/lexical-environment-simple-lookup.svg index 79501a5b0..e16223152 100644 --- a/1-js/06-advanced-functions/03-closure/lexical-environment-simple-lookup.svg +++ b/1-js/06-advanced-functions/03-closure/lexical-environment-simple-lookup.svg @@ -1 +1 @@ -say: function phrase: "Hello"name: "John"outerouternull \ No newline at end of file +say: hàm phrase: "Hello"name: "John"bên ngoàibên ngoàinull From c52ca7a4522d0248d7ec3467938067d4d3d8d741 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 18:17:28 +0700 Subject: [PATCH 49/83] Update lexical-environment-simple.svg --- .../03-closure/lexical-environment-simple.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/lexical-environment-simple.svg b/1-js/06-advanced-functions/03-closure/lexical-environment-simple.svg index dea6ac467..bc1b10d42 100644 --- a/1-js/06-advanced-functions/03-closure/lexical-environment-simple.svg +++ b/1-js/06-advanced-functions/03-closure/lexical-environment-simple.svg @@ -1 +1 @@ -say: function phrase: "Hello"name: "John"outerouternullLexical Environment of the call \ No newline at end of file +say: hàm phrase: "Hello"name: "John"bên ngoàibên ngoàinullLexical Environment của cuộc gọi From 0ccb59edd91c719ca5c9b6dfc7a5cb06f7b27adb Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 18:20:12 +0700 Subject: [PATCH 50/83] Update task.md --- .../03-closure/1-closure-latest-changes/task.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/1-closure-latest-changes/task.md b/1-js/06-advanced-functions/03-closure/1-closure-latest-changes/task.md index 819189773..8416d2362 100644 --- a/1-js/06-advanced-functions/03-closure/1-closure-latest-changes/task.md +++ b/1-js/06-advanced-functions/03-closure/1-closure-latest-changes/task.md @@ -2,9 +2,9 @@ importance: 5 --- -# Does a function pickup latest changes? +# Hàm có nhận thay đổi mới nhất không? -The function sayHi uses an external variable name. When the function runs, which value is it going to use? +Hàm sayHi sử dụng tên biến ngoài. Khi hàm chạy, nó sẽ sử dụng giá trị nào? ```js let name = "John"; @@ -15,9 +15,9 @@ function sayHi() { name = "Pete"; -sayHi(); // what will it show: "John" or "Pete"? +sayHi(); // nó sẽ hiển thị gì: "John" hay "Pete"? ``` -Such situations are common both in browser and server-side development. A function may be scheduled to execute later than it is created, for instance after a user action or a network request. +Những tình huống như vậy là phổ biến cả trong phát triển trình duyệt và phía máy chủ. Một hàm có thể được lên lịch để thực thi muộn hơn so với khi nó được tạo, chẳng hạn như sau một hành động của người dùng hoặc một yêu cầu mạng. -So, the question is: does it pick up the latest changes? +Vì vậy, câu hỏi là: nó có nhận những thay đổi mới nhất không? From e08d1506b499d88f10c5f64f8ee5544999841a88 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 18:21:10 +0700 Subject: [PATCH 51/83] Update solution.md --- .../03-closure/1-closure-latest-changes/solution.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/1-closure-latest-changes/solution.md b/1-js/06-advanced-functions/03-closure/1-closure-latest-changes/solution.md index 7cbd85ab7..84b56579e 100644 --- a/1-js/06-advanced-functions/03-closure/1-closure-latest-changes/solution.md +++ b/1-js/06-advanced-functions/03-closure/1-closure-latest-changes/solution.md @@ -1,5 +1,5 @@ -The answer is: **Pete**. +Đáp án là: **Pete**. -A function gets outer variables as they are now, it uses the most recent values. +Một hàm nhận các biến bên ngoài như hiện tại, nó sử dụng các giá trị gần đây nhất. -Old variable values are not saved anywhere. When a function wants a variable, it takes the current value from its own Lexical Environment or the outer one. +Giá trị biến cũ không được lưu ở bất cứ đâu. Khi một hàm muốn một biến, nó sẽ lấy giá trị hiện tại từ Lexical Environment của chính nó hoặc environment bên ngoài. From 586002ae88ebcac394ba2a6fd66ac252d4781a66 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 18:24:25 +0700 Subject: [PATCH 52/83] Update task.md --- .../03-closure/10-make-army/task.md | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/task.md b/1-js/06-advanced-functions/03-closure/10-make-army/task.md index f50c7dc20..2ed8cd52f 100644 --- a/1-js/06-advanced-functions/03-closure/10-make-army/task.md +++ b/1-js/06-advanced-functions/03-closure/10-make-army/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Army of functions +# Đội quân hàm -The following code creates an array of `shooters`. +Đoạn mã sau tạo ra một array của `shooters`. -Every function is meant to output its number. But something is wrong... +Mọi chức năng đều xuất ra số của nó. Nhưng có gì đó không ổn ... ```js run function makeArmy() { @@ -14,28 +14,28 @@ function makeArmy() { let i = 0; while (i < 10) { - let shooter = function() { // create a shooter function, - alert( i ); // that should show its number + let shooter = function() { // tạo một hàm shooter, + alert( i ); // điều đó nên hiển thị số của nó }; - shooters.push(shooter); // and add it to the array + shooters.push(shooter); // và thêm nó vào array i++; } - // ...and return the array of shooters + // ....và trả lại array shooter return shooters; } let army = makeArmy(); *!* -// all shooters show 10 instead of their numbers 0, 1, 2, 3... -army[0](); // 10 from the shooter number 0 -army[1](); // 10 from the shooter number 1 -army[2](); // 10 ...and so on. +// tất cả các shooter hiển thị 10 thay vì số của nchung1 0, 1, 2, 3... +army[0](); // 10 từ shooter số 0 +army[1](); // 10 từ shooter số 1 +army[2](); // 10 ... vân vân. */!* ``` -Why do all of the shooters show the same value? +Tại sao tất cả các shooter hiển thị cùng một giá trị? -Fix the code so that they work as intended. +Sửa mã để chúng hoạt động như dự định. From 4b1c1a4caff307a0553261af380a62843fca8be6 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 18:30:43 +0700 Subject: [PATCH 53/83] Update solution.md --- .../03-closure/10-make-army/solution.md | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/solution.md b/1-js/06-advanced-functions/03-closure/10-make-army/solution.md index 9d99aa717..961bc6abd 100644 --- a/1-js/06-advanced-functions/03-closure/10-make-army/solution.md +++ b/1-js/06-advanced-functions/03-closure/10-make-army/solution.md @@ -1,14 +1,14 @@ -Let's examine what exactly happens inside `makeArmy`, and the solution will become obvious. +Hãy xem xét chính xác điều gì xảy ra bên trong `makeArmy` và giải pháp sẽ trở nên rõ ràng. -1. It creates an empty array `shooters`: +1. Nó tạo ra một array `shooters` trống: ```js let shooters = []; ``` -2. Fills it with functions via `shooters.push(function)` in the loop. +2. Điền vào nó các hàm thông qua `shooters.push(function)` trong vòng lặp. - Every element is a function, so the resulting array looks like this: + Mỗi phần tử là một hàm, vì vậy array kết quả trông như thế này: ```js no-beautify shooters = [ @@ -25,40 +25,40 @@ Let's examine what exactly happens inside `makeArmy`, and the solution will beco ]; ``` -3. The array is returned from the function. +3. Array được trả về từ hàm. - Then, later, the call to any member, e.g. `army[5]()` will get the element `army[5]` from the array (which is a function) and calls it. + Sau đó, sau đó, cuộc gọi đến bất kỳ thành viên nào, ví dụ:. `army[5]()` sẽ lấy phần tử `army[5]` từ array (là một hàm) và gọi nó. - Now why do all such functions show the same value, `10`? + Bây giờ tại sao tất cả các chức năng như vậy hiển thị cùng một giá trị, `10`? - That's because there's no local variable `i` inside `shooter` functions. When such a function is called, it takes `i` from its outer lexical environment. + Đó là bởi vì không có biến cục bộ `i` bên trong các hàm `shooter`. Khi một hàm như vậy được gọi, nó sẽ lấy `i` từ lexical environment bên ngoài của nó. - Then, what will be the value of `i`? + Khi đó, giá trị của `i` sẽ là bao nhiêu? - If we look at the source: + Nếu chúng ta nhìn vào nguồn: ```js function makeArmy() { ... let i = 0; while (i < 10) { - let shooter = function() { // shooter function - alert( i ); // should show its number + let shooter = function() { // hàm shooter + alert( i ); // nên hiển thị số của nó }; - shooters.push(shooter); // add function to the array + shooters.push(shooter); // thêm hàm vào array i++; } ... } ``` - We can see that all `shooter` functions are created in the lexical environment of `makeArmy()` function. But when `army[5]()` is called, `makeArmy` has already finished its job, and the final value of `i` is `10` (`while` stops at `i=10`). + Chúng ta có thể thấy rằng tất cả các hàm `shooter` đều được tạo trong lexical environment của hàm `makeArmy()`. Nhưng khi `army[5]()` được gọi, `makeArmy` đã hoàn thành công việc của nó và giá trị cuối cùng của `i` là `10` (`while` dừng ở `i=10`). - As the result, all `shooter` functions get the same value from the outer lexical environment and that is, the last value, `i=10`. + Kết quả là, tất cả các hàm `shooter` nhận cùng một giá trị từ lexical environment bên ngoài và đó là giá trị cuối cùng, `i=10`. ![](lexenv-makearmy-empty.svg) - As you can see above, on each iteration of a `while {...}` block, a new lexical environment is created. So, to fix this, we can copy the value of `i` into a variable within the `while {...}` block, like this: + Như bạn có thể thấy ở trên, trên mỗi lần lặp của khối `while {...}`, một lexical environment mới được tạo. Vì vậy, để khắc phục điều này, chúng ta có thể sao chép giá trị của `i` vào một biến trong khối `while {...}`, như sau: ```js run function makeArmy() { @@ -69,8 +69,8 @@ Let's examine what exactly happens inside `makeArmy`, and the solution will beco *!* let j = i; */!* - let shooter = function() { // shooter function - alert( *!*j*/!* ); // should show its number + let shooter = function() { // hàm shooter + alert( *!*j*/!* ); // nên hiển thị số của nó }; shooters.push(shooter); i++; @@ -81,18 +81,18 @@ Let's examine what exactly happens inside `makeArmy`, and the solution will beco let army = makeArmy(); - // Now the code works correctly + // Bây giờ mã hoạt động đúng army[0](); // 0 army[5](); // 5 ``` - Here `let j = i` declares an "iteration-local" variable `j` and copies `i` into it. Primitives are copied "by value", so we actually get an independent copy of `i`, belonging to the current loop iteration. + Ở đây `let j = i` khai báo một biến "lặp cục bộ" `j` và sao chép `i` vào đó. Các bản gốc được sao chép "theo giá trị", vì vậy chúng ta thực sự nhận được một bản sao độc lập của `i`, thuộc về phép lặp vòng lặp hiện tại. The shooters work correctly, because the value of `i` now lives a little bit closer. Not in `makeArmy()` Lexical Environment, but in the Lexical Environment that corresponds to the current loop iteration: ![](lexenv-makearmy-while-fixed.svg) - Such a problem could also be avoided if we used `for` in the beginning, like this: + Vấn đề như vậy cũng có thể tránh được nếu chúng ta sử dụng `for` ngay từ đầu, như sau: ```js run demo function makeArmy() { @@ -102,8 +102,8 @@ Let's examine what exactly happens inside `makeArmy`, and the solution will beco *!* for(let i = 0; i < 10; i++) { */!* - let shooter = function() { // shooter function - alert( i ); // should show its number + let shooter = function() { // hàm shooter + alert( i ); // nên hiển thị số của nó }; shooters.push(shooter); } @@ -117,13 +117,13 @@ Let's examine what exactly happens inside `makeArmy`, and the solution will beco army[5](); // 5 ``` - That's essentially the same, because `for` on each iteration generates a new lexical environment, with its own variable `i`. So `shooter` generated in every iteration references its own `i`, from that very iteration. + Điều đó về cơ bản là giống nhau, bởi vì `for` trên mỗi lần lặp tạo ra một lexical environment mới, với biến riêng `i`. Vì vậy, `shooter` được tạo trong mỗi lần lặp tham chiếu `i` của chính nó, từ chính lần lặp đó. ![](lexenv-makearmy-for-fixed.svg) -Now, as you've put so much effort into reading this, and the final recipe is so simple - just use `for`, you may wonder -- was it worth that? +Bây giờ, vì bạn đã bỏ ra rất nhiều công sức để đọc nó, và công thức cuối cùng rất đơn giản - chỉ cần sử dụng `for`, bạn có thể tự hỏi -- nó có đáng không? -Well, if you could easily answer the question, you wouldn't read the solution. So, hopefully this task must have helped you to understand things a bit better. +Chà, nếu bạn có thể dễ dàng trả lời câu hỏi, bạn sẽ không đọc lời giải. Vì vậy, hy vọng nhiệm vụ này đã giúp bạn hiểu mọi thứ tốt hơn một chút. -Besides, there are indeed cases when one prefers `while` to `for`, and other scenarios, where such problems are real. +Bên cạnh đó, thực sự có những trường hợp khi một người thích `while` hơn là `for`, và các tình huống khác, trong đó các vấn đề như vậy là có thật. From a53cfc903940df3aba1511f50867527aa7c77b20 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 18:32:29 +0700 Subject: [PATCH 54/83] Update lexenv-makearmy-while-fixed.svg --- .../03-closure/10-make-army/lexenv-makearmy-while-fixed.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-while-fixed.svg b/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-while-fixed.svg index d83ecbe76..1da95bb77 100644 --- a/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-while-fixed.svg +++ b/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-while-fixed.svg @@ -1 +1 @@ -outerj: 0j: 1j: 2j: 10...makeArmy() LexicalEnvironmentwhile iteration LexicalEnvironment \ No newline at end of file +bên ngoàij: 0j: 1j: 2j: 10...makeArmy() LexicalEnvironmenttrong khi lặp LexicalEnvironment From 2f0ef5f7ad89b6f51873108e64cd8387f28e2c63 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 18:34:17 +0700 Subject: [PATCH 55/83] Update lexenv-makearmy-for-fixed.svg --- .../03-closure/10-make-army/lexenv-makearmy-for-fixed.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-for-fixed.svg b/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-for-fixed.svg index 7611d0ef8..2312642a4 100644 --- a/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-for-fixed.svg +++ b/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-for-fixed.svg @@ -1 +1 @@ -outermakeArmy() LexicalEnvironmentfor iteration LexicalEnvironmenti: 0i: 1i: 2i: 10... \ No newline at end of file +bên ngoàimakeArmy() LexicalEnvironmentđể lặp LexicalEnvironmenti: 0i: 1i: 2i: 10... From d1388baad70cb4ea034eed1fcfe8527ebef99c1c Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 18:35:33 +0700 Subject: [PATCH 56/83] Update lexenv-makearmy-empty.svg --- .../03-closure/10-make-army/lexenv-makearmy-empty.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-empty.svg b/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-empty.svg index f8c7bd6ac..eda799360 100644 --- a/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-empty.svg +++ b/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-empty.svg @@ -1 +1 @@ -outer<empty>makeArmy() LexicalEnvironmentwhile iteration LexicalEnvironment<empty><empty><empty>i: 10 \ No newline at end of file +bên ngoài<trống>makeArmy() LexicalEnvironmentwhile iteration LexicalEnvironment<trống><trống><trống>i: 10 From 4712bdb27230383ff6e89a702071c6a964b0cf18 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 18:35:56 +0700 Subject: [PATCH 57/83] Update solution.js --- .../03-closure/10-make-army/_js.view/solution.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/_js.view/solution.js b/1-js/06-advanced-functions/03-closure/10-make-army/_js.view/solution.js index a26578ae1..9d7e4b35a 100644 --- a/1-js/06-advanced-functions/03-closure/10-make-army/_js.view/solution.js +++ b/1-js/06-advanced-functions/03-closure/10-make-army/_js.view/solution.js @@ -3,8 +3,8 @@ function makeArmy() { let shooters = []; for(let i = 0; i < 10; i++) { - let shooter = function() { // shooter function - alert( i ); // should show its number + let shooter = function() { // hàm shooter + alert( i ); // nên hiện số của nó }; shooters.push(shooter); } From be8977f8172cc8f286700b7018a7940512faa048 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 18:37:00 +0700 Subject: [PATCH 58/83] Update source.js --- .../03-closure/10-make-army/_js.view/source.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/_js.view/source.js b/1-js/06-advanced-functions/03-closure/10-make-army/_js.view/source.js index 7c7aaa1e3..dcd71d8b9 100644 --- a/1-js/06-advanced-functions/03-closure/10-make-army/_js.view/source.js +++ b/1-js/06-advanced-functions/03-closure/10-make-army/_js.view/source.js @@ -3,8 +3,8 @@ function makeArmy() { let i = 0; while (i < 10) { - let shooter = function() { // shooter function - alert( i ); // should show its number + let shooter = function() { // hàm shooter + alert( i ); // nên hiện số của nó }; shooters.push(shooter); i++; @@ -16,7 +16,7 @@ function makeArmy() { /* let army = makeArmy(); -army[0](); // the shooter number 0 shows 10 -army[5](); // and number 5 also outputs 10... -// ... all shooters show 10 instead of their 0, 1, 2, 3... +army[0](); // shooter số 0 hiển thị 10 +army[5](); // và số 5 cũng ra 10... +// ... tất cả các shooter hiển thị 10 thay vì số của chúng 0, 1, 2, 3... */ From ab8799e8cbb3dd345f3ada3dc3de37f5cdf62851 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 18:37:19 +0700 Subject: [PATCH 59/83] Update task.md --- 1-js/06-advanced-functions/03-closure/10-make-army/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/task.md b/1-js/06-advanced-functions/03-closure/10-make-army/task.md index 2ed8cd52f..ccdd3bcbe 100644 --- a/1-js/06-advanced-functions/03-closure/10-make-army/task.md +++ b/1-js/06-advanced-functions/03-closure/10-make-army/task.md @@ -28,7 +28,7 @@ function makeArmy() { let army = makeArmy(); *!* -// tất cả các shooter hiển thị 10 thay vì số của nchung1 0, 1, 2, 3... +// tất cả các shooter hiển thị 10 thay vì số của chúng 0, 1, 2, 3... army[0](); // 10 từ shooter số 0 army[1](); // 10 từ shooter số 1 army[2](); // 10 ... vân vân. From de8624ec31029120312c1b232cfc9200cf9c59db Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 18:38:31 +0700 Subject: [PATCH 60/83] Update task.md --- .../03-closure/2-closure-variable-access/task.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/2-closure-variable-access/task.md b/1-js/06-advanced-functions/03-closure/2-closure-variable-access/task.md index d12a385c8..bb14dd538 100644 --- a/1-js/06-advanced-functions/03-closure/2-closure-variable-access/task.md +++ b/1-js/06-advanced-functions/03-closure/2-closure-variable-access/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Which variables are available? +# Những biến nào có sẵn? -The function `makeWorker` below makes another function and returns it. That new function can be called from somewhere else. +Hàm `makeWorker` bên dưới tạo một hàm khác và trả về hàm đó. Hàm mới đó có thể được gọi từ một nơi khác. -Will it have access to the outer variables from its creation place, or the invocation place, or both? +Nó sẽ có quyền truy cập vào các biến bên ngoài từ nơi tạo của nó, hay nơi gọi, hay cả hai? ```js function makeWorker() { @@ -19,11 +19,11 @@ function makeWorker() { let name = "John"; -// create a function +// tạo một hàm let work = makeWorker(); -// call it -work(); // what will it show? +// gọi nó +work(); // nó sẽ hiển thị những gì? ``` -Which value it will show? "Pete" or "John"? +Nó sẽ hiển thị giá trị nào? "Pete" hay "John"? From 9d06bfa0b22a688d1bf6997e7c061011a11f6b41 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 18:39:28 +0700 Subject: [PATCH 61/83] Update solution.md --- .../03-closure/2-closure-variable-access/solution.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/2-closure-variable-access/solution.md b/1-js/06-advanced-functions/03-closure/2-closure-variable-access/solution.md index 0a522132f..e172084c1 100644 --- a/1-js/06-advanced-functions/03-closure/2-closure-variable-access/solution.md +++ b/1-js/06-advanced-functions/03-closure/2-closure-variable-access/solution.md @@ -1,9 +1,9 @@ -The answer is: **Pete**. +Đáp án là: **Pete**. -The `work()` function in the code below gets `name` from the place of its origin through the outer lexical environment reference: +Hàm `work()` trong đoạn mã bên dưới lấy `name` từ nơi xuất phát của nó thông qua tham chiếu lexical environment bên ngoài: ![](lexenv-nested-work.svg) -So, the result is `"Pete"` here. +Vì vậy, kết quả là `"Pete"` ở đây. -But if there were no `let name` in `makeWorker()`, then the search would go outside and take the global variable as we can see from the chain above. In that case the result would be `"John"`. +Nhưng nếu không có `let name` trong `makeWorker()`, thì tìm kiếm sẽ ra bên ngoài và lấy biến chung như chúng ta có thể thấy từ chuỗi bên trên. Trong trường hợp đó, kết quả sẽ là `"John"`. From 251255cb0aa972c1197ba0afb1b3bf6895be34b6 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 18:43:14 +0700 Subject: [PATCH 62/83] Update lexenv-nested-work.svg --- .../03-closure/2-closure-variable-access/lexenv-nested-work.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/2-closure-variable-access/lexenv-nested-work.svg b/1-js/06-advanced-functions/03-closure/2-closure-variable-access/lexenv-nested-work.svg index 8dfd8bd63..e1131e6cb 100644 --- a/1-js/06-advanced-functions/03-closure/2-closure-variable-access/lexenv-nested-work.svg +++ b/1-js/06-advanced-functions/03-closure/2-closure-variable-access/lexenv-nested-work.svg @@ -1 +1 @@ -makeWorker: function name: "John"<empty>outerouterouternullname: "Pete" \ No newline at end of file +makeWorker: hàm name: "John"<trống>bên ngoàibên ngoàibên ngoàinullname: "Pete" From 1efc4b95258bfb5f806f12ccc5cac05430d54299 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 20:09:54 +0700 Subject: [PATCH 63/83] Update task.md --- .../03-closure/3-counter-independent/task.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/3-counter-independent/task.md b/1-js/06-advanced-functions/03-closure/3-counter-independent/task.md index e8c17dd31..82843eda8 100644 --- a/1-js/06-advanced-functions/03-closure/3-counter-independent/task.md +++ b/1-js/06-advanced-functions/03-closure/3-counter-independent/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Are counters independent? +# Bộ đếm có độc lập không? -Here we make two counters: `counter` and `counter2` using the same `makeCounter` function. +Ở đây chúng ta tạo hai bộ đếm: `counter` và `counter2` bằng cách sử dụng cùng hàm `makeCounter`. -Are they independent? What is the second counter going to show? `0,1` or `2,3` or something else? +Chúng có độc lập không? Bộ đếm thứ hai sẽ hiển thị là gì? `0,1` hay `2,3` hay cái gì khác? ```js function makeCounter() { From 5b1b1eef3a248cb7570eae2a0908e1fe3551b6d0 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 20:10:52 +0700 Subject: [PATCH 64/83] Update solution.md --- .../03-closure/3-counter-independent/solution.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/3-counter-independent/solution.md b/1-js/06-advanced-functions/03-closure/3-counter-independent/solution.md index 25ecbea4c..6ce5294f2 100644 --- a/1-js/06-advanced-functions/03-closure/3-counter-independent/solution.md +++ b/1-js/06-advanced-functions/03-closure/3-counter-independent/solution.md @@ -1,5 +1,5 @@ -The answer: **0,1.** +Đáp án: **0,1.** -Functions `counter` and `counter2` are created by different invocations of `makeCounter`. +Các hàm `counter` và `counter2` được tạo bởi các lệnh gọi khác nhau của `makeCounter`. -So they have independent outer Lexical Environments, each one has its own `count`. +Vì vậy, chúng có các Lexical Environment bên ngoài độc lập, mỗi môi trường có `count` riêng. From 9bd3d038929b413366f78f694497770359659bc5 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 20:11:41 +0700 Subject: [PATCH 65/83] Update task.md --- .../03-closure/4-counter-object-independent/task.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/4-counter-object-independent/task.md b/1-js/06-advanced-functions/03-closure/4-counter-object-independent/task.md index d770b0ffc..ceeed0478 100644 --- a/1-js/06-advanced-functions/03-closure/4-counter-object-independent/task.md +++ b/1-js/06-advanced-functions/03-closure/4-counter-object-independent/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Counter object +# Đối tượng bộ đếm -Here a counter object is made with the help of the constructor function. +Ở đây, một đối tượng bộ đếm được tạo với sự trợ giúp của hàm tạo. -Will it work? What will it show? +Nó có hoạt động không? Nó sẽ hiển thị cái gì? ```js function Counter() { From 93fcf08b473eebb99f277ce97ea3c7606de82338 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 20:12:14 +0700 Subject: [PATCH 66/83] Update solution.md --- .../03-closure/4-counter-object-independent/solution.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/4-counter-object-independent/solution.md b/1-js/06-advanced-functions/03-closure/4-counter-object-independent/solution.md index cd4e641e4..e7dcbd95b 100644 --- a/1-js/06-advanced-functions/03-closure/4-counter-object-independent/solution.md +++ b/1-js/06-advanced-functions/03-closure/4-counter-object-independent/solution.md @@ -1,7 +1,7 @@ -Surely it will work just fine. +Chắc chắn nó sẽ hoạt động tốt. -Both nested functions are created within the same outer Lexical Environment, so they share access to the same `count` variable: +Cả hai hàm lồng nhau đều được tạo trong cùng một Lexical Environment bên ngoài, vì vậy chúng chia sẻ quyền truy cập vào cùng một biến `count`: ```js run function Counter() { From 9462ff10f19154e06474b56c0dfe3a5fa5cc524a Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 20:12:43 +0700 Subject: [PATCH 67/83] Update task.md --- .../06-advanced-functions/03-closure/5-function-in-if/task.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/5-function-in-if/task.md b/1-js/06-advanced-functions/03-closure/5-function-in-if/task.md index d02c53b99..1ae2da19c 100644 --- a/1-js/06-advanced-functions/03-closure/5-function-in-if/task.md +++ b/1-js/06-advanced-functions/03-closure/5-function-in-if/task.md @@ -1,7 +1,7 @@ -# Function in if +# Hàm trong if -Look at the code. What will be the result of the call at the last line? +Nhìn vào mã. Cái gì sẽ là kết quả của cuộc gọi ở dòng cuối cùng? ```js run let phrase = "Hello"; From daffeaf7d4e5e38dc33daff9023bb51217bf1b40 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 20:13:00 +0700 Subject: [PATCH 68/83] Update solution.md --- .../03-closure/5-function-in-if/solution.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/5-function-in-if/solution.md b/1-js/06-advanced-functions/03-closure/5-function-in-if/solution.md index e2e7a91b3..e4b93af54 100644 --- a/1-js/06-advanced-functions/03-closure/5-function-in-if/solution.md +++ b/1-js/06-advanced-functions/03-closure/5-function-in-if/solution.md @@ -1,3 +1,3 @@ -The result is **an error**. +Kết quả là **một lỗi**. -The function `sayHi` is declared inside the `if`, so it only lives inside it. There is no `sayHi` outside. \ No newline at end of file +Hàm `sayHi` được khai báo bên trong `if`, vì vậy nó chỉ tồn tại bên trong nó. Không có `sayHi` bên ngoài. From 9939895e887cc1da4198bed3e50bb4585efb7afd Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 20:13:34 +0700 Subject: [PATCH 69/83] Update task.md --- .../03-closure/6-closure-sum/task.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/6-closure-sum/task.md b/1-js/06-advanced-functions/03-closure/6-closure-sum/task.md index b45758562..731af3f86 100644 --- a/1-js/06-advanced-functions/03-closure/6-closure-sum/task.md +++ b/1-js/06-advanced-functions/03-closure/6-closure-sum/task.md @@ -2,13 +2,13 @@ importance: 4 --- -# Sum with closures +# Tổng với bao đóng -Write function `sum` that works like this: `sum(a)(b) = a+b`. +Viết hàm `sum` hoạt động như sau: `sum(a)(b) = a+b`. -Yes, exactly this way, using double parentheses (not a mistype). +Vâng, chính xác theo cách này, sử dụng dấu ngoặc kép (không phải gõ nhầm). -For instance: +Ví dụ: ```js sum(1)(2) = 3 From f5eec0eb1957b5b5738580b07aea45dd00f52aaa Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 20:13:46 +0700 Subject: [PATCH 70/83] Update task.md --- 1-js/06-advanced-functions/03-closure/6-closure-sum/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/6-closure-sum/task.md b/1-js/06-advanced-functions/03-closure/6-closure-sum/task.md index 731af3f86..3a9f70170 100644 --- a/1-js/06-advanced-functions/03-closure/6-closure-sum/task.md +++ b/1-js/06-advanced-functions/03-closure/6-closure-sum/task.md @@ -2,7 +2,7 @@ importance: 4 --- -# Tổng với bao đóng +# Tổng có bao đóng Viết hàm `sum` hoạt động như sau: `sum(a)(b) = a+b`. From be7da6645951779fdd30f7d6081cd338b555b04f Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 20:14:32 +0700 Subject: [PATCH 71/83] Update solution.md --- .../03-closure/6-closure-sum/solution.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/6-closure-sum/solution.md b/1-js/06-advanced-functions/03-closure/6-closure-sum/solution.md index a6679cd20..33b2e8575 100644 --- a/1-js/06-advanced-functions/03-closure/6-closure-sum/solution.md +++ b/1-js/06-advanced-functions/03-closure/6-closure-sum/solution.md @@ -1,12 +1,12 @@ -For the second parentheses to work, the first ones must return a function. +Để các dấu ngoặc đơn thứ hai hoạt động, các dấu ngoặc đơn đầu tiên phải trả về một hàm. -Like this: +Như thế này: ```js run function sum(a) { return function(b) { - return a + b; // takes "a" from the outer lexical environment + return a + b; // lấy "a" từ lexical environment bên ngoài }; } From 2a43201f3d745ec49659de76f5b4f8724210b2f8 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 20:15:31 +0700 Subject: [PATCH 72/83] Update task.md --- 1-js/06-advanced-functions/03-closure/7-let-scope/task.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/7-let-scope/task.md b/1-js/06-advanced-functions/03-closure/7-let-scope/task.md index fb7445e66..ce1bebb7c 100644 --- a/1-js/06-advanced-functions/03-closure/7-let-scope/task.md +++ b/1-js/06-advanced-functions/03-closure/7-let-scope/task.md @@ -2,9 +2,9 @@ importance: 4 --- -# Is variable visible? +# Biến có thể nhìn thấy không? -What will be the result of this code? +Cái gì sẽ là kết quả của mã này? ```js let x = 1; @@ -18,4 +18,4 @@ function func() { func(); ``` -P.S. There's a pitfall in this task. The solution is not obvious. +Tái bút: Có một cạm bẫy trong nhiệm vụ này. Lời giải không rõ ràng. From 492335b3c115b6f8aac3565c8959ac2583be415a Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 20:17:24 +0700 Subject: [PATCH 73/83] Update solution.md --- .../03-closure/7-let-scope/solution.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md b/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md index b16b35290..d23b5f070 100644 --- a/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md +++ b/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md @@ -1,6 +1,6 @@ -The result is: **error**. +Kết quả là: **lỗi**. -Try running it: +Hãy thử chạy nó: ```js run let x = 1; @@ -15,20 +15,20 @@ function func() { func(); ``` -In this example we can observe the peculiar difference between a "non-existing" and "uninitialized" variable. +Trong ví dụ này, chúng ta có thể quan sát sự khác biệt đặc biệt giữa biến "không tồn tại" và "chưa được khởi tạo". -As you may have read in the article [](info:closure), a variable starts in the "uninitialized" state from the moment when the execution enters a code block (or a function). And it stays uninitalized until the corresponding `let` statement. +Như bạn có thể đã đọc trong bài viết [](info: closure), một biến bắt đầu ở trạng thái "chưa được khởi tạo" kể từ thời điểm khi quá trình thực thi đi vào một khối mã (hoặc một hàm). Và nó vẫn chưa được khởi tạo cho đến câu lệnh `let` tương ứng. -In other words, a variable technically exists, but can't be used before `let`. +Nói cách khác, một biến tồn tại về mặt kỹ thuật, nhưng không thể được sử dụng trước `let`. -The code above demonstrates it. +Đoạn mã trên chứng minh điều đó. ```js function func() { *!* - // the local variable x is known to the engine from the beginning of the function, - // but "uninitialized" (unusable) until let ("dead zone") - // hence the error + // biến cục bộ x được biết đến với engine từ khi bắt đầu hàm, + // nhưng "chưa được khởi tạo" (không sử dụng được) cho đến khi let ("vùng chết") + // do đó lỗi */!* console.log(x); // ReferenceError: Cannot access 'x' before initialization @@ -37,4 +37,4 @@ function func() { } ``` -This zone of temporary unusability of a variable (from the beginning of the code block till `let`) is sometimes called the "dead zone". +Vùng tạm thời không sử dụng được của một biến (từ đầu khối mã cho đến `let`) đôi khi được gọi là "vùng chết". From 09d2e63518e245b06bc756fc36068bbfb67a3a5e Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 20:17:53 +0700 Subject: [PATCH 74/83] Update task.md --- 1-js/06-advanced-functions/03-closure/7-let-scope/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/7-let-scope/task.md b/1-js/06-advanced-functions/03-closure/7-let-scope/task.md index ce1bebb7c..ff6697026 100644 --- a/1-js/06-advanced-functions/03-closure/7-let-scope/task.md +++ b/1-js/06-advanced-functions/03-closure/7-let-scope/task.md @@ -2,7 +2,7 @@ importance: 4 --- -# Biến có thể nhìn thấy không? +# Có thể nhìn thấy biến này không? Cái gì sẽ là kết quả của mã này? From db7d52cd65caa4b0dee847dc20f1dcab84d48064 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 20:19:25 +0700 Subject: [PATCH 75/83] Update task.md --- .../8-filter-through-function/task.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/8-filter-through-function/task.md b/1-js/06-advanced-functions/03-closure/8-filter-through-function/task.md index d1c39f949..92314dad3 100644 --- a/1-js/06-advanced-functions/03-closure/8-filter-through-function/task.md +++ b/1-js/06-advanced-functions/03-closure/8-filter-through-function/task.md @@ -2,24 +2,24 @@ importance: 5 --- -# Filter through function +# Lọc qua hàm -We have a built-in method `arr.filter(f)` for arrays. It filters all elements through the function `f`. If it returns `true`, then that element is returned in the resulting array. +Chúng ta có một phương thức tích hợp sẵn `arr.filter(f)` cho các array. Nó lọc tất cả các phần tử thông qua hàm `f`. Nếu nó trả về `true`, thì phần tử đó được trả về trong array kết quả. -Make a set of "ready to use" filters: +Tạo một tập hợp các bộ lọc "sẵn sàng sử dụng": -- `inBetween(a, b)` -- between `a` and `b` or equal to them (inclusively). -- `inArray([...])` -- in the given array. +- `inBetween(a, b)` -- giữa `a` và `b` hoặc bằng chúng (bao gồm cả). +- `inArray([...])` -- trong array đã cho. -The usage must be like this: +Việc sử dụng phải như thế này: -- `arr.filter(inBetween(3,6))` -- selects only values between 3 and 6. -- `arr.filter(inArray([1,2,3]))` -- selects only elements matching with one of the members of `[1,2,3]`. +- `arr.filter(inBetween(3,6))` -- chỉ chọn các giá trị từ 3 đến 6. +- `arr.filter(inArray([1,2,3]))` -- chỉ chọn các phần tử khớp với một trong các phần tử của `[1,2,3]`. -For instance: +Ví dụ: ```js -/* .. your code for inBetween and inArray */ +/* .. mã của bạn cho inBetween và inArray */ let arr = [1, 2, 3, 4, 5, 6, 7]; alert( arr.filter(inBetween(3, 6)) ); // 3,4,5,6 From 9e754ad45fbbc4cc824438c6b84513cb7c2eb0b0 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 20:19:40 +0700 Subject: [PATCH 76/83] Update solution.md --- .../03-closure/8-filter-through-function/solution.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/8-filter-through-function/solution.md b/1-js/06-advanced-functions/03-closure/8-filter-through-function/solution.md index 46c5514a8..2b272020b 100644 --- a/1-js/06-advanced-functions/03-closure/8-filter-through-function/solution.md +++ b/1-js/06-advanced-functions/03-closure/8-filter-through-function/solution.md @@ -1,5 +1,5 @@ -# Filter inBetween +# Lọc inBetween ```js run function inBetween(a, b) { @@ -12,7 +12,7 @@ let arr = [1, 2, 3, 4, 5, 6, 7]; alert( arr.filter(inBetween(3, 6)) ); // 3,4,5,6 ``` -# Filter inArray +# Lọc inArray ```js run demo function inArray(arr) { From e575ae58ba5a95e4ffd4da63d5c89a24b53c02b7 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 20:20:12 +0700 Subject: [PATCH 77/83] Update source.js --- .../03-closure/8-filter-through-function/_js.view/source.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/8-filter-through-function/_js.view/source.js b/1-js/06-advanced-functions/03-closure/8-filter-through-function/_js.view/source.js index 74989df28..6ecc45017 100644 --- a/1-js/06-advanced-functions/03-closure/8-filter-through-function/_js.view/source.js +++ b/1-js/06-advanced-functions/03-closure/8-filter-through-function/_js.view/source.js @@ -2,9 +2,9 @@ let arr = [1, 2, 3, 4, 5, 6, 7]; function inBetween(a, b) { - // ...your code... + // ...mã của bạn... } function inArray(arr) { - // ...your code... + // ...mã của bạn... } From 0a5c3fcd5463875cea944d83a0ec0a3f255b0d18 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 20:21:30 +0700 Subject: [PATCH 78/83] Update task.md --- .../03-closure/9-sort-by-field/task.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/9-sort-by-field/task.md b/1-js/06-advanced-functions/03-closure/9-sort-by-field/task.md index 08fb5cc34..9d961625e 100644 --- a/1-js/06-advanced-functions/03-closure/9-sort-by-field/task.md +++ b/1-js/06-advanced-functions/03-closure/9-sort-by-field/task.md @@ -2,9 +2,9 @@ importance: 5 --- -# Sort by field +# Sắp xếp theo lĩnh vực -We've got an array of objects to sort: +Chúng ta đã có một array các đối tượng để sắp xếp: ```js let users = [ @@ -14,23 +14,23 @@ let users = [ ]; ``` -The usual way to do that would be: +Cách thông thường để làm điều đó sẽ là: ```js -// by name (Ann, John, Pete) +// theo tên (Ann, John, Pete) users.sort((a, b) => a.name > b.name ? 1 : -1); -// by age (Pete, Ann, John) +// theo tuổi (Pete, Ann, John) users.sort((a, b) => a.age > b.age ? 1 : -1); ``` -Can we make it even less verbose, like this? +Chúng ta có thể làm cho nó ít dài dòng hơn như thế này không? ```js users.sort(byField('name')); users.sort(byField('age')); ``` -So, instead of writing a function, just put `byField(fieldName)`. +Vì vậy, thay vì viết một hàm, chỉ cần đặt `byField(fieldName)`. -Write the function `byField` that can be used for that. +Viết hàm `byField` có thể được sử dụng cho việc đó. From 08ef5964c24364241f1635a474d96eb206cabb2e Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 20:21:53 +0700 Subject: [PATCH 79/83] Update source.js --- .../03-closure/9-sort-by-field/_js.view/source.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/source.js b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/source.js index 23b433834..903a78659 100644 --- a/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/source.js +++ b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/source.js @@ -1,5 +1,5 @@ function byField(fieldName){ - // Your code goes here. + // Mã của bạn ở đây. } From c50d02ba912702a0a4333789c802d520312e442f Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 20:52:15 +0700 Subject: [PATCH 80/83] Update solution.md --- 1-js/06-advanced-functions/03-closure/7-let-scope/solution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md b/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md index d23b5f070..5b7b3d0fd 100644 --- a/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md +++ b/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md @@ -17,7 +17,7 @@ func(); Trong ví dụ này, chúng ta có thể quan sát sự khác biệt đặc biệt giữa biến "không tồn tại" và "chưa được khởi tạo". -Như bạn có thể đã đọc trong bài viết [](info: closure), một biến bắt đầu ở trạng thái "chưa được khởi tạo" kể từ thời điểm khi quá trình thực thi đi vào một khối mã (hoặc một hàm). Và nó vẫn chưa được khởi tạo cho đến câu lệnh `let` tương ứng. +Như bạn có thể đã đọc trong [bài viết](info: closure), một biến bắt đầu ở trạng thái "chưa được khởi tạo" kể từ thời điểm khi quá trình thực thi đi vào một khối mã (hoặc một hàm). Và nó vẫn chưa được khởi tạo cho đến câu lệnh `let` tương ứng. Nói cách khác, một biến tồn tại về mặt kỹ thuật, nhưng không thể được sử dụng trước `let`. From 56deede2f4c1f91a8ebae7fcd3a86049cb634065 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 20:53:36 +0700 Subject: [PATCH 81/83] Update solution.md --- 1-js/06-advanced-functions/03-closure/7-let-scope/solution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md b/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md index 5b7b3d0fd..d23b5f070 100644 --- a/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md +++ b/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md @@ -17,7 +17,7 @@ func(); Trong ví dụ này, chúng ta có thể quan sát sự khác biệt đặc biệt giữa biến "không tồn tại" và "chưa được khởi tạo". -Như bạn có thể đã đọc trong [bài viết](info: closure), một biến bắt đầu ở trạng thái "chưa được khởi tạo" kể từ thời điểm khi quá trình thực thi đi vào một khối mã (hoặc một hàm). Và nó vẫn chưa được khởi tạo cho đến câu lệnh `let` tương ứng. +Như bạn có thể đã đọc trong bài viết [](info: closure), một biến bắt đầu ở trạng thái "chưa được khởi tạo" kể từ thời điểm khi quá trình thực thi đi vào một khối mã (hoặc một hàm). Và nó vẫn chưa được khởi tạo cho đến câu lệnh `let` tương ứng. Nói cách khác, một biến tồn tại về mặt kỹ thuật, nhưng không thể được sử dụng trước `let`. From 8502b4dcf6e3d42346bd25c58b232634e8925d8c Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 20:54:28 +0700 Subject: [PATCH 82/83] Update solution.md --- .../03-closure/3-counter-independent/solution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/3-counter-independent/solution.md b/1-js/06-advanced-functions/03-closure/3-counter-independent/solution.md index 6ce5294f2..4ab14b213 100644 --- a/1-js/06-advanced-functions/03-closure/3-counter-independent/solution.md +++ b/1-js/06-advanced-functions/03-closure/3-counter-independent/solution.md @@ -2,4 +2,4 @@ Các hàm `counter` và `counter2` được tạo bởi các lệnh gọi khác nhau của `makeCounter`. -Vì vậy, chúng có các Lexical Environment bên ngoài độc lập, mỗi môi trường có `count` riêng. +Vì vậy, chúng có các Lexical Environment bên ngoài độc lập, mỗi environment có `count` riêng. From 3af0ffb7b70fa6660f26548c7b0f70dc7d99e0ec Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Mon, 5 Jun 2023 20:54:47 +0700 Subject: [PATCH 83/83] Update solution.md --- .../03-closure/2-closure-variable-access/solution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/03-closure/2-closure-variable-access/solution.md b/1-js/06-advanced-functions/03-closure/2-closure-variable-access/solution.md index e172084c1..c5f69bcb3 100644 --- a/1-js/06-advanced-functions/03-closure/2-closure-variable-access/solution.md +++ b/1-js/06-advanced-functions/03-closure/2-closure-variable-access/solution.md @@ -6,4 +6,4 @@ Hàm `work()` trong đoạn mã bên dưới lấy `name` từ nơi xuất phát Vì vậy, kết quả là `"Pete"` ở đây. -Nhưng nếu không có `let name` trong `makeWorker()`, thì tìm kiếm sẽ ra bên ngoài và lấy biến chung như chúng ta có thể thấy từ chuỗi bên trên. Trong trường hợp đó, kết quả sẽ là `"John"`. +Nhưng nếu không có `let name` trong `makeWorker()`, thì tìm kiếm sẽ ra bên ngoài và lấy biến cục bộ như chúng ta có thể thấy từ chuỗi bên trên. Trong trường hợp đó, kết quả sẽ là `"John"`.