JavaScript là một ngôn ngữ phức tạp. Nếu bạn là nhà phát triển JavaScript ở mọi cấp độ, điều quan trọng là phải hiểu các khái niệm cơ bản của nó. Bài viết này giải quyết 12 khái niệm quan trọng mà bất kỳ nhà phát triển JS nào cũng phải hiểu, nhưng không có cách nào trình bày toàn bộ những gì một nhà phát triển JS nên biết
Ghi chú. Nếu bạn thích bài viết này, xin hãy vỗ tay 👏 [hoặc 50. ] để giúp quảng bá
Tôi sẽ liên tục cập nhật danh sách này trong kho lưu trữ Github có tên là JS Tips and Tidbits. Hãy đánh dấu sao ⭐ và chia sẻ nếu bạn muốn theo dõi cùng
1. Giá trị so với. Gán biến tham chiếu
Hiểu cách JavaScript gán cho các biến là nền tảng để viết JavaScript không có lỗi. Nếu bạn không hiểu điều này, bạn có thể dễ dàng viết mã làm thay đổi giá trị ngoài ý muốn
JavaScript luôn gán các biến theo giá trị. Nhưng phần này rất quan trọng. khi giá trị được gán là một trong năm kiểu nguyên thủy của JavaScript [i. e. , Boolean
, null
, undefined
, String
và Number
] giá trị thực tế được chỉ định. Tuy nhiên, khi giá trị được gán là Array
, Function
hoặc Object
thì tham chiếu đến đối tượng trong bộ nhớ được gán
thời gian ví dụ. Trong đoạn mã sau, var2
được đặt bằng với var1
. Vì var1
là kiểu nguyên thủy [String
], nên var2
được đặt bằng với giá trị String
của var1
và có thể được coi là hoàn toàn khác biệt với var1
tại thời điểm này. Theo đó, việc chỉ định lại var2
không có hiệu lực đối với null
7
let var1 = 'Chuỗi của tôi';let var2 = var1;
var2 = 'Chuỗi mới của tôi';
bảng điều khiển. log[var1];// 'Chuỗi của tôi'console. log[var2];// 'Chuỗi mới của tôi'
Hãy so sánh điều này với gán đối tượng
hãy để var1 = { tên. 'Jim' }hãy để var2 = var1;
var2. tên = 'John';
bảng điều khiển. nhật ký [var1]; // { tên. 'John' }bảng điều khiển. nhật ký [var2]; // { tên. 'John' }
Người ta có thể thấy điều này có thể gây ra vấn đề như thế nào nếu bạn mong đợi hành vi như phép gán nguyên thủy. Điều này có thể trở nên đặc biệt xấu nếu bạn tạo một hàm vô tình thay đổi một đối tượng
2. đóng cửa
Đóng cửa là một mẫu JavaScript quan trọng để cấp quyền truy cập riêng tư vào một biến. Trong ví dụ này, null
8 trả về một hàm ẩn danh có quyền truy cập vào null
9 được cung cấp, “Xin chào. ” Đối với tất cả các mục đích sử dụng trong tương lai, undefined
0 sẽ có quyền truy cập vào lời chào này
function createGreeter[lời chào] {return function[name] {console. log[lời chào + ', ' + tên];}}
const sayXin chào = createGreeter['Xin chào'];sayXin chào['Joe'];// Xin chào, Joe
Trong một tình huống thực tế hơn, bạn có thể hình dung một hàm ban đầu undefined
1 trả về một số phương thức sẽ sử dụng khóa API. Trong trường hợp này, undefined
2 sẽ chỉ cần được cung cấp một lần và không bao giờ lặp lại
function api Connect[api Key] {function get[route] {return fetch[`${root}?key=${apiKey}`];}
chức năng đăng [tuyến đường, thông số] {trả về tìm nạp [tuyến đường, undefined
3]}
trả lại { nhận, đăng }}
const api = apiConnect['my-secret-key'];
// Không cần thêm apiKey nữaapi. lấy ['http. //www. ví dụ. com/get-end'];api. bài đăng ['http. //www. ví dụ. com/post-endpoint', { tên. 'Joe' }];
3. hủy diệt
Đừng bị loại bỏ bởi việc phá hủy tham số JavaScript. Đó là một cách phổ biến để trích xuất rõ ràng các thuộc tính từ các đối tượng
const obj = {tên. 'Joe', thức ăn. 'bánh ngọt'}
const {tên, món ăn} = obj;
bảng điều khiển. log[tên, món ăn];// 'Joe' 'bánh'
Nếu bạn muốn trích xuất các thuộc tính dưới một tên khác, bạn có thể chỉ định chúng bằng định dạng sau
const obj = {tên. 'Joe', thức ăn. 'bánh ngọt'}
const { tên. myName, thức ăn. myFood } = obj;
bảng điều khiển. log[Tên của tôi, Thức ăn của tôi];// 'Joe' 'bánh'
Trong ví dụ sau, phá hủy được sử dụng để chuyển hoàn toàn đối tượng undefined
4 sang hàm undefined
5. Nói cách khác, phá hủy có thể [và thường là] được sử dụng trực tiếp để trích xuất các tham số được truyền cho hàm. Nếu bạn đã quen thuộc với React, có thể bạn đã từng thấy điều này trước đây
const người = {tên. 'Eddie', tuổi. 24}
chức năng giới thiệu [{tên, tuổi}] {bảng điều khiển. log[`Tôi là ${name} và tôi là ${age} tuổi. `];}
bảng điều khiển. log[introduce[person]];// "Tôi là Eddie và tôi 24 tuổi. "
4. Cú pháp lây lan
Một khái niệm JavaScript có thể khiến mọi người thất vọng nhưng tương đối đơn giản là toán tử trải rộng. Trong trường hợp sau, không thể áp dụng undefined
6 cho mảng undefined
7 vì nó không lấy một mảng làm đối số, nó lấy các phần tử riêng lẻ làm đối số. Toán tử trải rộng undefined
8 được sử dụng để lấy các phần tử riêng lẻ ra khỏi mảng
const mảng = [4, 6, -1, 3, 10, 4];const max = Toán học. tối đa [. mảng]; bảng điều khiển. nhật ký [tối đa]; // 10
5. Nghỉ Cú pháp
Hãy nói về cú pháp nghỉ ngơi JavaScript. Bạn có thể sử dụng nó để đặt bất kỳ số lượng đối số nào được truyền cho một hàm vào một mảng
hàm myFunc[. args] {bảng điều khiển. log[args[0] + args[1]];}
myFunc[1, 2, 3, 4];// 3
6. Phương thức mảng
Các phương thức mảng JavaScript thường có thể cung cấp cho bạn những cách tinh tế, đáng kinh ngạc để thực hiện chuyển đổi dữ liệu mà bạn cần. Là người đóng góp cho StackOverflow, tôi thường thấy các câu hỏi liên quan đến cách thao tác một mảng đối tượng theo cách này hay cách khác. Đây có xu hướng là trường hợp sử dụng hoàn hảo cho các phương thức mảng
Tôi sẽ đề cập đến một số phương thức mảng khác nhau ở đây, được tổ chức bởi các phương thức tương tự đôi khi bị lẫn lộn. Danh sách này không phải là toàn diện. Tôi khuyến khích bạn xem xét và thực hành [tài liệu tham khảo JavaScript yêu thích của tôi]
**map, filter, reduce**Có một số nhầm lẫn xung quanh các phương thức mảng JavaScript undefined
9, String
0, String
1. Đây là những phương thức hữu ích để chuyển đổi một mảng hoặc trả về một giá trị tổng hợp
- bản đồ. trả về mảng trong đó mỗi phần tử được biến đổi theo chỉ định của hàm
const mảng = [1, 2, 3, 4, 5, 6];const ánh xạ = mảng. bản đồ[el => el + 20];
bảng điều khiển. log[ánh xạ];// [21, 22, 23, 24, 25, 26]
- lọc. trả về mảng các phần tử trong đó hàm trả về true
const mảng = [1, 2, 3, 4, 5, 6];const lọc = mảng. bộ lọc [el => el === 2. el===4];
bảng điều khiển. nhật ký [đã lọc]; // [2, 4]
- giảm. tích lũy các giá trị như được chỉ định trong chức năng
const mảng = [1, 2, 3, 4, 5, 6];const giảm = mảng. giảm [[tổng, hiện tại] => tổng + hiện tại];
bảng điều khiển. nhật ký [giảm]; // 21
**find, findIndex, indexOf**Các phương thức mảng String
2, String
3 và String
4 thường có thể được kết hợp. Sử dụng chúng như sau
- tìm thấy. trả lại phiên bản đầu tiên phù hợp với tiêu chí đã chỉ định. Không tiến triển để tìm bất kỳ trường hợp phù hợp nào khác
const mảng = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];const found = mảng. tìm[el => el > 5];
bảng điều khiển. nhật ký [tìm thấy]; // 6
Một lần nữa, lưu ý rằng mặc dù mọi thứ sau String
5 đều đáp ứng tiêu chí, nhưng chỉ phần tử phù hợp đầu tiên được trả về. Điều này thực sự cực kỳ hữu ích trong các tình huống mà bạn thường thực hiện một vòng lặp for khi tìm thấy kết quả phù hợp
- tìm Index. Điều này hoạt động gần như giống hệt với
String
2, nhưng thay vì trả về phần tử khớp đầu tiên, nó trả về chỉ mục của phần tử khớp đầu tiên. Lấy ví dụ sau, sử dụng tên thay vì số cho rõ ràng
const arr = ['Nick', 'Frank', 'Joe', 'Frank'];const foundIndex = arr. find Index[el => el === 'Frank'];
bảng điều khiển. log[foundIndex];// 1
- Chỉ số. Hoạt động gần như giống hệt với
String
3, nhưng thay vì lấy một hàm làm đối số, nó nhận một giá trị đơn giản. Bạn có thể sử dụng điều này khi bạn có logic đơn giản hơn và không cần sử dụng hàm để kiểm tra xem có khớp hay không
const arr = ['Nick', 'Frank', 'Joe', 'Frank'];const foundIndex = arr. indexOf['Frank'];
bảng điều khiển. log[foundIndex];// 1
**push, pop, shift, unshift**Có rất nhiều phương pháp mảng tuyệt vời để giúp thêm hoặc xóa các phần tử khỏi mảng theo cách được nhắm mục tiêu
- đẩy. Đây là một phương pháp tương đối đơn giản để thêm một phần tử vào cuối một mảng. Nó sửa đổi mảng tại chỗ và chính hàm trả về mục được thêm vào mảng
để mảng = [1, 2, 3, 4];const đẩy = mảng. đẩy[5];
bảng điều khiển. log[mảng];// [1, 2, 3, 4, 5] bảng điều khiển. nhật ký [được đẩy]; // 5
- nhạc pop. Điều này loại bỏ mục cuối cùng từ một mảng. Một lần nữa, nó sửa đổi mảng tại chỗ. Hàm tự trả về mục bị xóa khỏi mảng
let arr = [1, 2, 3, 4];const popped = arr. nhạc pop[];
bảng điều khiển. log[mảng];// [1, 2, 3] bảng điều khiển. nhật ký [xuất hiện]; // 4
- sự thay đổi. Điều này loại bỏ mục đầu tiên khỏi một mảng. Một lần nữa, nó sửa đổi mảng tại chỗ. Hàm tự trả về mục bị xóa khỏi mảng
let arr = [1, 2, 3, 4];const shift = arr. sự thay đổi[];
bảng điều khiển. log[mảng];// [2, 3, 4] bảng điều khiển. nhật ký [đã dịch chuyển]; // 1
- không dịch chuyển. Thao tác này thêm một hoặc nhiều phần tử vào đầu mảng. Một lần nữa, nó sửa đổi mảng tại chỗ. Không giống như nhiều phương thức khác, hàm tự trả về độ dài mới của mảng
let arr = [1, 2, 3, 4];const unshifted = arr. unshift[5, 6, 7];
bảng điều khiển. log[arr];// [5, 6, 7, 1, 2, 3, 4] bảng điều khiển. nhật ký [không dịch chuyển]; // 7
**splice, slice** Các phương thức này sửa đổi hoặc trả về các tập hợp con của mảng
- mối nối. Thay đổi nội dung của một mảng bằng cách loại bỏ hoặc thay thế các phần tử hiện có và/hoặc thêm các phần tử mới. Phương pháp này sửa đổi mảng tại chỗ
Mẫu mã sau đây có thể được đọc là. tại vị trí String
9 của mảng, loại bỏ phần tử Number
0 và chèn Number
1
let arr = ['a', 'c', 'd', 'e'];arr. mối nối [1, 0, 'b']
- lát cắt. trả về một bản sao nông của một mảng từ một vị trí bắt đầu đã chỉ định và trước một vị trí kết thúc đã chỉ định. Nếu không chỉ định vị trí kết thúc, phần còn lại của mảng được trả về. Điều quan trọng, phương thức này không sửa đổi mảng tại chỗ mà trả về tập hợp con mong muốn
let arr = ['a', 'b', 'c', 'd', 'e'];const slice = arr. lát [2, 4];
bảng điều khiển. log[sliced];// ['c', 'd']console. log[arr];// ['a', 'b', 'c', 'd', 'e']
loại
- loại. sắp xếp một mảng dựa trên hàm được cung cấp có đối số phần tử thứ nhất và phần tử thứ hai. Sửa đổi mảng tại chỗ. Nếu hàm trả về âm hoặc 0, thứ tự không thay đổi. Nếu dương, thứ tự phần tử được chuyển
let arr = [1, 7, 3, -1, 5, 7, 2];const sorter = [firstEl, secondEl] => firstEl - secondEl;arr. sắp xếp[sắp xếp];
bảng điều khiển. log[mảng];// [-1, 1, 2, 3, 5, 7, 7]
Phew, bạn đã bắt được tất cả những thứ đó chưa? . Trên thực tế, tôi đã phải tham khảo tài liệu MDN rất nhiều khi viết bài này — và điều đó không sao cả. Chỉ cần biết loại phương pháp nào hiện có sẽ giúp bạn đạt được 95%
7. máy phát điện
Đừng sợ ________ 42. Hàm tạo chỉ định những gì Number
3 được tạo ra vào lần tới khi Number
4 được gọi. Có thể có một số lượng lợi nhuận hữu hạn, sau đó, Number
4 trả về một Number
3 không xác định hoặc một số lượng giá trị vô hạn bằng cách sử dụng một vòng lặp
function* helloer[] {yield 'Xin chào';yield 'Bạn khỏe không?';yield 'Tạm biệt';}
const chào = lời chào[];
bảng điều khiển. nhật ký [chào. tiếp theo[]. giá trị]; // 'Xin chào'console. nhật ký [chào. tiếp theo[]. value];// 'Bạn có khỏe không?'console. nhật ký [chào. tiếp theo[]. giá trị]; // 'Bye'console. nhật ký [chào. tiếp theo[]. giá trị]; // không xác định
Và sử dụng trình tạo cho các giá trị vô hạn
function* idCreator[] {let i = 0;while [true]yield i++;}
const ids = idCreator[];
bảng điều khiển. nhật ký [id. tiếp theo[]. giá trị]; // 0 bảng điều khiển. nhật ký [id. tiếp theo[]. giá trị]; // 1 bảng điều khiển. nhật ký [id. tiếp theo[]. giá trị]; // 2 // v.v.
8. Toán tử nhận dạng [Number
7] so với. Toán tử bình đẳng [Number
8]
Đảm bảo biết sự khác biệt giữa toán tử đồng nhất [________ 47] và toán tử đẳng thức [________ 48] trong JavaScript. Toán tử Number
8 sẽ thực hiện chuyển đổi loại trước khi so sánh các giá trị trong khi toán tử Number
7 sẽ không thực hiện bất kỳ chuyển đổi loại nào trước khi so sánh
bảng điều khiển. log[0 == '0'];// trueconsole. nhật ký [0 === '0']; // sai
9. So sánh đối tượng
Một lỗi mà tôi thấy những người mới sử dụng JavaScript mắc phải là so sánh trực tiếp các đối tượng. Các biến đang trỏ đến các tham chiếu đến các đối tượng trong bộ nhớ, không phải chính các đối tượng đó. Một phương pháp để thực sự so sánh chúng là chuyển đổi các đối tượng thành chuỗi JSON. Điều này có một nhược điểm mặc dù. thứ tự thuộc tính đối tượng không được đảm bảo. Một cách an toàn hơn để so sánh các đối tượng là lấy trong thư viện chuyên so sánh đối tượng sâu [e. g. , ]
Các đối tượng sau đây có vẻ giống nhau nhưng thực tế chúng trỏ đến các tham chiếu khác nhau
const joe1 = {tên. 'Joe' };const joe2 = { tên. 'Joe' };
bảng điều khiển. nhật ký [joe1 === joe2]; // sai
Ngược lại, những điều sau đây đánh giá là đúng vì một đối tượng được đặt bằng đối tượng kia và do đó đang trỏ đến cùng một tham chiếu [chỉ có một đối tượng trong bộ nhớ]
const joe1 = {tên. 'Joe' };const joe2 = joe1;
bảng điều khiển. nhật ký [joe1 === joe2]; // đúng
Đảm bảo xem lại Giá trị so với. Phần tham khảo ở trên để hiểu đầy đủ về sự phân nhánh của việc đặt một biến bằng với một biến khác đang trỏ đến một tham chiếu đến một đối tượng trong bộ nhớ
10. Chức năng gọi lại
Quá nhiều người bị đe dọa bởi các chức năng gọi lại JavaScript. Chúng rất đơn giản, lấy ví dụ này. Hàm Array
3 đang được chuyển dưới dạng gọi lại cho Array
4. Nó được thực thi khi Array
5 hoàn thành. Thats tất cả để có nó
function myFunc[text, callback] {setTimeout[function[] {callback[text];}, 2000];}
myFunc['Xin chào thế giới. ', bảng điều khiển. log];// 'Xin chào thế giới. '
11. lời hứa
Một khi bạn hiểu các lệnh gọi lại JavaScript, bạn sẽ sớm thấy mình trong “địa ngục gọi lại” lồng nhau. ” Đây là nơi Lời hứa giúp đỡ. Gói logic không đồng bộ của bạn trong một Lời hứa và Array
6 nếu thành công hoặc Array
7 nếu thất bại. Sử dụng “then” để xử lý thành công và Array
8 để xử lý thất bại
const myPromise = new Promise[function[res, rej] {setTimeout[function[]{if [Toán. ngẫu nhiên[] < 0. 9] {return res['Hoan hô. '];}return rej['Ồ không. '];}, 1000];}];
lời hứa của tôi. sau đó [hàm [dữ liệu] {bảng điều khiển. log['Thành công. ' + dữ liệu];}]. bắt [chức năng [err] {bảng điều khiển. nhật ký ['Lỗi. ' + sai];}];
// Nếu Toán. ngẫu nhiên [] trả về ít hơn 0. 9 mục sau được ghi lại. // "Thành công. hoan hô. "// Nếu Toán. ngẫu nhiên[] trả về 0. 9 hoặc lớn hơn những điều sau đây được ghi lại. // "Lỗi. trên không. "
12. Không đồng bộ Đang chờ
Khi bạn hiểu rõ về các lời hứa JavaScript, bạn có thể thích Array
9, đây chỉ là "đường cú pháp" trên đầu các lời hứa. Trong ví dụ sau, chúng tôi tạo một hàm Function
0 và trong đó chúng tôi Function
1 lời hứa Function
2
const helloer = new Promise[[res, rej] => {setTimeout[[] => res['Xin chào thế giới. '], 2000];}]
chức năng không đồng bộ myFunc[] {const chào = chờ chào; bảng điều khiển. nhật ký [lời chào];}
myFunc[];// 'Xin chào thế giới. '
Phần kết luận
Nếu bạn không biết bất kỳ khái niệm nào trong số 12 khái niệm này, thì có lẽ bạn đã nâng cao ít nhất một chút kiến thức về JavaScript của mình. Và nếu bạn biết tất cả, thì hy vọng đây là cơ hội để thực hành và nâng cao kiến thức của bạn. Những khái niệm nào khác mà bạn nghĩ là quan trọng?