TL;DR
Về lý thuyết, một phiên bản không được tối ưu hóa của vòng lặp này:, an unoptimized version of this loop:
for [let i = 0; i < 500; ++i] {
doSomethingWith[i];
}
có thể chậm hơn một phiên bản không được tối ưu hóa của cùng một vòng với
for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9:for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
Bởi vì một biến
function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
0 khác nhau được tạo cho mỗi lần lặp lại với function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
1, trong khi đó chỉ có một function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
0 với for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9.different function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
0 variable is created for each loop iteration with function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
1, whereas there's only one function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
0 with for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9.Lập luận chống lại điều đó là thực tế
9 được nâng lên nên nó được tuyên bố bên ngoài vòng lặp trong khi for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
1 chỉ được khai báo trong vòng lặp, có thể mang lại lợi thế tối ưu hóa. is the fact the function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9 is hoisted so it's declared outside the loop whereas
the function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
1 is only declared within the loop, which may offer an optimization advantage.Trong thực tế, ở đây vào năm 2018, các động cơ JavaScript hiện đại làm đủ hướng nội của vòng lặp để biết khi nào nó có thể tối ưu hóa sự khác biệt đó. ., here in 2018, modern JavaScript engines do enough introspection of the loop to know when it can optimize that difference away. [Even before then, odds are your loop was doing enough work that the additional
function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
1-related overhead was washed out anyway. But now you don't even have to worry about it.]Hãy coi chừng điểm chuẩn tổng hợp vì chúng cực kỳ dễ hiểu và kích hoạt các trình tối ưu hóa công cụ JavaScript theo cách mà mã thực không [cả cách tốt và xấu]. Tuy nhiên, nếu bạn muốn có một điểm chuẩn tổng hợp, đây là một điểm: as they are extremely easy to get wrong, and trigger JavaScript engine optimizers in ways that real code doesn't [both good and bad ways]. However, if you want a synthetic benchmark, here's one:
Nó nói rằng không có sự khác biệt đáng kể trong thử nghiệm tổng hợp trên V8/Chrome hoặc Spidermonkey/Firefox. . Lo lắng về hiệu suất của mã của bạn khi và nếu mã của bạn có vấn đề về hiệu suất.
Như một vấn đề về phong cách, tôi thích
function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
1 cho lợi ích phạm vi và lợi ích đóng cửa trong vòng lặp nếu tôi sử dụng biến vòng lặp trong việc đóng.Thông tin chi tiết
Sự khác biệt quan trọng giữa
for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9 và function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
1 trong vòng lặp var greeter = "hey hi";
function newFunction[] {
var hello = "hello";
}
0 là một function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
0 khác nhau được tạo cho mỗi lần lặp; Nó giải quyết vấn đề "đóng cửa trong vòng lặp" cổ điển:Tạo môi trường mới cho mỗi cơ thể vòng lặp [liên kết thông số kỹ thuật] là công việc và công việc cần có thời gian, đó là lý do tại sao phiên bản
function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
1 chậm hơn phiên bản for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9.Nhưng sự khác biệt chỉ quan trọng nếu bạn tạo một hàm [đóng] trong vòng lặp sử dụng
function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
0, như tôi đã làm trong ví dụ đoạn trích có thể chạy ở trên. Nếu không, sự khác biệt không thể được quan sát và có thể được tối ưu hóa.Ở đây vào năm 2018, có vẻ như V8 [và Spidermonkey trong Firefox] đang thực hiện đủ hướng nội rằng không có chi phí hiệu suất trong một vòng lặp không sử dụng ngữ nghĩa thay đổi theo đơn vị của ____ 21. Xem bài kiểm tra này.
Trong một số trường hợp,
var greeter = "hey hi";
function newFunction[] {
var hello = "hello";
}
6 cũng có thể cung cấp một cơ hội để tối ưu hóa rằng for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9 sẽ không, đặc biệt là đối với các biến toàn cầu.Vấn đề với một biến toàn cầu là nó, tốt, toàn cầu; Bất kỳ mã bất cứ nơi nào cũng có thể truy cập nó. Vì vậy, nếu bạn khai báo một biến với
for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9 mà bạn không bao giờ có ý định thay đổi [và không bao giờ thay đổi mã của mình], động cơ không thể cho rằng nó sẽ không bao giờ thay đổi do kết quả của mã được tải sau hoặc tương tự.any code
anywhere could access it. So if you declare a variable with for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9 that you never intend to change [and never do change in your code], the engine can't assume it's never going to change as the result of code loaded later or similar.Tuy nhiên, với
var greeter = "hey hi";
function newFunction[] {
var hello = "hello";
}
6, bạn đang nói rõ ràng rằng giá trị không thể thay đổi. Vì vậy, miễn phí thực hiện bất kỳ tối ưu hóa nào mà nó muốn, bao gồm phát ra một nghĩa đen thay vì một tham chiếu biến để sử dụng mã, biết rằng các giá trị không thể thay đổi.Hãy nhớ rằng với các đối tượng, giá trị là một tham chiếu đến đối tượng, không phải chính đối tượng. Vì vậy, với
var tester = "hey hi";
function newFunction[] {
var hello = "hello";
}
console.log[hello]; // error: hello is not defined
0, bạn có thể thay đổi trạng thái của đối tượng [ var tester = "hey hi";
function newFunction[] {
var hello = "hello";
}
console.log[hello]; // error: hello is not defined
1], nhưng bạn không thể tạo var tester = "hey hi";
function newFunction[] {
var hello = "hello";
}
console.log[hello]; // error: hello is not defined
2 trỏ đến một đối tượng mới [vì điều đó sẽ yêu cầu thay đổi tham chiếu đối tượng mà nó chứa].Khi sử dụng
function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
1 hoặc var greeter = "hey hi";
function newFunction[] {
var hello = "hello";
}
6 trong các tình huống giống như ____ 19 khác, chúng không có khả năng có hiệu suất khác nhau. Chức năng này phải có hiệu suất chính xác cho dù bạn sử dụng for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9 hay function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
1, ví dụ:function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
Tất nhiên, đó là tất cả, không có khả năng quan trọng và một cái gì đó phải lo lắng chỉ nếu và khi có một vấn đề thực sự cần giải quyết.
Rất nhiều tính năng mới sáng bóng đã xuất hiện với ES2015 [ES6]. Và bây giờ, kể từ năm 2020, người ta cho rằng rất nhiều nhà phát triển JavaScript đã làm quen và đã bắt đầu sử dụng các tính năng này. Mặc dù giả định này có thể đúng một phần, nhưng vẫn có thể một số tính năng này vẫn là một bí ẩn đối với một số nhà phát triển. Một trong những tính năng đi kèm với ES6 là bổ sung
1 và function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
6, có thể được sử dụng để khai báo biến. Câu hỏi đặt ra là, điều gì làm cho chúng khác với ol ' var greeter = "hey hi";
function newFunction[] {
var hello = "hello";
}
9 mà chúng ta đã sử dụng? Nếu bạn vẫn chưa rõ về điều này, thì bài viết này là dành cho bạn.for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
Trong bài viết này, chúng tôi sẽ thảo luận về
for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9, function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
1 và var greeter = "hey hi";
function newFunction[] {
var hello = "hello";
}
6 & nbsp; đối với phạm vi, sử dụng và nâng cao của chúng. Khi bạn đọc, hãy lưu ý về sự khác biệt giữa chúng mà tôi sẽ chỉ ra.Trước sự ra đời của ES6,
for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9 tuyên bố cai trị. Mặc dù vậy, có những vấn đề liên quan đến các biến được khai báo với for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9. Đó là lý do tại sao nó cần thiết cho những cách mới để khai báo các biến xuất hiện. Đầu tiên, chúng ta hãy hiểu thêm for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9 trước khi chúng ta thảo luận về những vấn đề đó.Phạm vi của var
Phạm vi về cơ bản có nghĩa là nơi các biến này có sẵn để sử dụng.
9 Khai báo được phạm vi toàn cầu hoặc chức năng/phạm vi cục bộ. essentially means where these variables are available for use. for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9 declarations are globally scoped or function/locally scoped. Phạm vi là toàn cầu khi biến
for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9 được khai báo bên ngoài hàm. Điều này có nghĩa là bất kỳ biến nào được khai báo với for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9 bên ngoài một khối hàm có sẵn để sử dụng trong toàn bộ cửa sổ.for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9 là chức năng phạm vi khi nó được khai báo trong một hàm. Điều này có nghĩa là nó có sẵn và chỉ có thể được truy cập trong chức năng đó.Để hiểu thêm, hãy nhìn vào ví dụ dưới đây.
var greeter = "hey hi";
function newFunction[] {
var hello = "hello";
}
Ở đây,
var greeter = "hey hi";
greeter = "say Hello instead";
1 được phạm vi toàn cầu vì nó tồn tại bên ngoài một hàm trong khi var greeter = "hey hi";
greeter = "say Hello instead";
2 là chức năng phạm vi. Vì vậy, chúng tôi không thể truy cập biến var greeter = "hey hi";
greeter = "say Hello instead";
2 bên ngoài hàm. Vì vậy, nếu chúng ta làm điều này: var tester = "hey hi";
function newFunction[] {
var hello = "hello";
}
console.log[hello]; // error: hello is not defined
Chúng tôi sẽ gặp lỗi do
var greeter = "hey hi";
greeter = "say Hello instead";
2 không có sẵn bên ngoài chức năng.Các biến VAR có thể được khai báo lại và cập nhật
Điều này có nghĩa là chúng ta có thể làm điều này trong cùng một phạm vi và sẽ không gặp lỗi.
var greeter = "hey hi";
var greeter = "say Hello instead";
Và điều này cũng
var greeter = "hey hi";
greeter = "say Hello instead";
Nâng var var
Tăng cường là một cơ chế JavaScript trong đó các biến và khai báo chức năng được chuyển lên đầu phạm vi của chúng trước khi thực hiện mã. Điều này có nghĩa là nếu chúng ta làm điều này:
console.log [greeter];
var greeter = "say hello"
Nó được giải thích như thế này:
var greeter;
console.log[greeter]; // greeter is undefined
greeter = "say hello"
Vì vậy, các biến
for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9 được nâng lên đỉnh phạm vi của chúng và được khởi tạo với giá trị var greeter = "hey hi";
greeter = "say Hello instead";
6.Vấn đề với var
Có một điểm yếu đi kèm với & nbsp; ________ 19. Tôi sẽ sử dụng ví dụ dưới đây để giải thích:
var greeter = "hey hi";
var times = 4;
if [times > 3] {
var greeter = "say Hello instead";
}
console.log[greeter] // "say Hello instead"
Vì vậy, vì
var greeter = "hey hi";
greeter = "say Hello instead";
8 trả về đúng, var greeter = "hey hi";
greeter = "say Hello instead";
1 được xác định lại & nbsp; đến console.log [greeter];
var greeter = "say hello"
0. Mặc dù đây không phải là vấn đề nếu bạn cố tình muốn var greeter = "hey hi";
greeter = "say Hello instead";
1 được xác định lại, nhưng nó sẽ trở thành một vấn đề khi bạn không nhận ra rằng một biến var greeter = "hey hi";
greeter = "say Hello instead";
1 đã được xác định trước đó.Nếu bạn đã sử dụng
var greeter = "hey hi";
greeter = "say Hello instead";
1 trong các phần khác trong mã của mình, bạn có thể ngạc nhiên về đầu ra mà bạn có thể nhận được. Điều này có thể sẽ gây ra rất nhiều lỗi trong mã của bạn. Đây là lý do tại sao function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
1 và var greeter = "hey hi";
function newFunction[] {
var hello = "hello";
}
6 là cần thiết.Để cho
function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
1 hiện được ưa thích cho khai báo biến. Không có gì ngạc nhiên khi nó là một cải tiến cho các tuyên bố for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9. Nó cũng giải quyết vấn đề với for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9 mà chúng tôi vừa đề cập. Hãy xem xét tại sao điều này là như vậy.Đặt phạm vi khối
Một khối là một đoạn mã giới hạn bởi {}. Một khối sống trong niềng răng xoăn. Bất cứ điều gì trong niềng răng xoăn là một khối.
Vì vậy, một biến được khai báo trong một khối với
function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
1 & nbsp; chỉ có sẵn để sử dụng trong khối đó. Hãy để tôi giải thích điều này với một ví dụ:for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
0Chúng tôi thấy rằng sử dụng
var greeter = "hey hi";
greeter = "say Hello instead";
2 bên ngoài khối của nó [niềng răng xoăn nơi nó được xác định] trả về một lỗi. Điều này là do các biến function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
1 là phạm vi khối.Có thể cập nhật nhưng không được khai báo lại.
Giống như
for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9, & nbsp; một biến được khai báo với function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
1 có thể được cập nhật trong phạm vi của nó. Không giống như for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9, biến function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
1 không thể được khai báo lại trong phạm vi của nó. Vì vậy, trong khi điều này sẽ hoạt động:for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
1Điều này sẽ trả về một lỗi:
for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
2Tuy nhiên, nếu cùng một biến được xác định trong các phạm vi khác nhau, sẽ không có lỗi:
for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
3Tại sao không có lỗi? Điều này là do cả hai trường hợp được coi là các biến khác nhau vì chúng có phạm vi khác nhau.
Thực tế này làm cho
function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
1 là một lựa chọn tốt hơn so với for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9. Khi sử dụng function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
1, bạn không cần phải bận tâm nếu bạn đã sử dụng tên cho một biến trước đây vì một biến chỉ tồn tại trong phạm vi của nó.Ngoài ra, vì một biến không thể được khai báo nhiều lần trong phạm vi, nên vấn đề được thảo luận trước đó xảy ra với
for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9 không xảy ra.Nâng cấp cho
Giống như & nbsp; ________ 19,
function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
1 Tuyên bố được nâng lên hàng đầu. Không giống như for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
9 được khởi tạo là var greeter = "hey hi";
greeter = "say Hello instead";
6, từ khóa function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
1 không được khởi tạo. Vì vậy, nếu bạn cố gắng sử dụng biến function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
1 trước khi khai báo, bạn sẽ nhận được var greeter = "hey hi";
var times = 4;
if [times > 3] {
var greeter = "say Hello instead";
}
console.log[greeter] // "say Hello instead"
6.Hằng số
Các biến được khai báo với
var greeter = "hey hi";
function newFunction[] {
var hello = "hello";
}
6 duy trì các giá trị không đổi. var greeter = "hey hi";
function newFunction[] {
var hello = "hello";
}
6 Tuyên bố chia sẻ một số điểm tương đồng với khai báo function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
1.Tuyên bố const là phạm vi khối
Giống như các khai báo
function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
1, các khai báo var greeter = "hey hi";
function newFunction[] {
var hello = "hello";
}
6 chỉ có thể được truy cập trong khối mà chúng được khai báo.const không thể được cập nhật hoặc tuyên bố lại
Điều này có nghĩa là giá trị của một biến được khai báo với
var greeter = "hey hi";
function newFunction[] {
var hello = "hello";
}
6 vẫn giữ nguyên trong phạm vi của nó. Nó không thể được cập nhật hoặc tuyên bố lại. Vì vậy, nếu chúng tôi khai báo một biến với var greeter = "hey hi";
function newFunction[] {
var hello = "hello";
}
6, chúng tôi không thể làm điều này:for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
4Cũng không phải điều này:
for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
5Mỗi tuyên bố
var greeter = "hey hi";
function newFunction[] {
var hello = "hello";
}
6, do đó, phải được khởi tạo tại thời điểm khai báo.Hành vi này bằng cách nào đó khác nhau khi nói đến các đối tượng được tuyên bố với
var greeter = "hey hi";
function newFunction[] {
var hello = "hello";
}
6. Mặc dù đối tượng var greeter = "hey hi";
function newFunction[] {
var hello = "hello";
}
6 không thể được cập nhật, các thuộc tính của các đối tượng này có thể được cập nhật. Do đó, nếu chúng ta khai báo một đối tượng var greeter = "hey hi";
function newFunction[] {
var hello = "hello";
}
6 như thế này:for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
6Trong khi chúng ta không thể làm điều này:
for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
7chung ta co thể lam được việc nay:
for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
8Điều này sẽ cập nhật giá trị của
for [var i = 0; i < 500; ++i] {
doSomethingWith[i];
}
08 mà không phải trả lại lỗi.Nâng cao const
Giống như
function foo[] {
var i = 0;
while [Math.random[] < 0.5] {
++i;
}
return i;
}
1, var greeter = "hey hi";
function newFunction[] {
var hello = "hello";
}
6 Tuyên bố được nâng lên trên cùng nhưng không được khởi tạo.Vì vậy, chỉ trong trường hợp bạn bỏ lỡ sự khác biệt, đây là:
- Các khai báo
9 được phạm vi toàn cầu hoặc chức năng trong khifor [var i = 0; i < 500; ++i] { doSomethingWith[i]; }
1 vàfunction foo[] { var i = 0; while [Math.random[] < 0.5] { ++i; } return i; }
6 là phạm vi khối.var greeter = "hey hi"; function newFunction[] { var hello = "hello"; }
9 Các biến có thể được cập nhật và khai báo lại trong phạm vi của nó;for [var i = 0; i < 500; ++i] { doSomethingWith[i]; }
1 Các biến có thể được cập nhật nhưng không được khai báo lại;function foo[] { var i = 0; while [Math.random[] < 0.5] { ++i; } return i; }
6 Các biến không thể được cập nhật cũng như không được khai báo.var greeter = "hey hi"; function newFunction[] { var hello = "hello"; }
- Họ đều được nâng lên đỉnh phạm vi của họ. Nhưng trong khi các biến
9 được khởi tạo với các biếnfor [var i = 0; i < 500; ++i] { doSomethingWith[i]; }
6,var greeter = "hey hi"; greeter = "say Hello instead";
1 vàfunction foo[] { var i = 0; while [Math.random[] < 0.5] { ++i; } return i; }
6 không được khởi tạo.var greeter = "hey hi"; function newFunction[] { var hello = "hello"; }
- Trong khi
9 vàfor [var i = 0; i < 500; ++i] { doSomethingWith[i]; }
1 có thể được khai báo mà không được khởi tạo,function foo[] { var i = 0; while [Math.random[] < 0.5] { ++i; } return i; }
6 phải được khởi tạo trong quá trình khai báo.var greeter = "hey hi"; function newFunction[] { var hello = "hello"; }
Có bất kỳ câu hỏi hoặc bổ sung? Làm ơn cho tôi biết.
Cảm ơn bạn đã đọc :]
Học mã miễn phí. Chương trình giảng dạy nguồn mở của Freecodecamp đã giúp hơn 40.000 người có được việc làm với tư cách là nhà phát triển. Bắt đầu