- vừa được xem lúc

JavaScript Nâng Cao - Kỳ 12

0 0 8

Người đăng: NGUYỄN ANH TUẤN

Theo Viblo Asia

Có một câu nói vui là: Trên đời chỉ có thứ nhiều người chửi và thứ không ai thèm dùng.

Javascript là một ví dụ điển hình, nó có một số điểm thú vị nhưng cũng khiến chúng ta phải đau đầu. Lý thuyết thì dễ hiểu, nhưng khi thực hành là cả một vấn đề. Vậy nên, mình sẽ cùng các bạn đi sâu vào từng ví dụ cụ thể và phân tích, mổ xẻ nó để hiểu hơn về Javascript nhé.

Series này có thể sẽ khá dài mình không biết sẽ có bao nhiêu Kỳ tuy nhiên để tiện cho các bạn nào không đọc các bài trước đó của mình về JS thì trong loạt bài này mình sẽ giải thích lại toàn bộ. Các lý thuyết trong loạt bài này mình cũng có thể sẽ giải thích lại nhiều lần (tùy hứng) để các bạn có thể năm rõ nó hơn nhé.

Ok vào bài thôi nào... GÉT GÔ 🚀

Nếu có bất kỳ câu hỏi nào đừng ngại hãy bình luận dưới phần comment nhé. Hoặc chỉ cần để lại một comment chào mình là đã giúp mình có thêm động lực hoàn thành series này. Cảm ơn các bạn rất nhiều. 🤗

1. Set và các giá trị duy nhất

Output của đoạn code bên dưới là gì:

const set = new Set([1, 1, 2, 3, 4]); console.log(set);
  • A: [1, 1, 2, 3, 4]
  • B: [1, 2, 3, 4]
  • C: {1, 1, 2, 3, 4}
  • D: {1, 2, 3, 4}
Đáp án của câu hỏi này là ↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
Đáp án: D

Cùng mình đi tìm hiểu tại sao kết quả lại là như vậy nhé ❓️

1.1. Set trong JavaScript

Set là một cấu trúc dữ liệu trong JavaScript được giới thiệu từ ES6. Nó cho phép bạn lưu trữ các giá trị duy nhất của bất kỳ kiểu dữ liệu nào, bao gồm cả các giá trị nguyên thủy và các tham chiếu đối tượng.

1.2. Đặc điểm của Set

  1. Giá trị duy nhất: Mỗi giá trị trong Set chỉ có thể xuất hiện một lần. Nếu bạn thêm một giá trị đã tồn tại, nó sẽ bị bỏ qua.

  2. Thứ tự chèn: Set giữ nguyên thứ tự chèn của các phần tử. Điều này có nghĩa là khi bạn lặp qua một Set, các phần tử sẽ được trả về theo thứ tự chúng được chèn vào.

  3. Không có chỉ mục: Không giống như mảng, Set không có chỉ mục. Bạn không thể truy cập các phần tử bằng chỉ mục.

1.3. Phân tích đoạn code

Trong đoạn code của chúng ta:

const set = new Set([1, 1, 2, 3, 4]);

Chúng ta đang tạo một Set mới và khởi tạo nó với một mảng [1, 1, 2, 3, 4]. Set sẽ tự động loại bỏ các giá trị trùng lặp. Trong trường hợp này, giá trị 1 xuất hiện hai lần trong mảng ban đầu, nhưng Set chỉ giữ lại một lần.

Khi chúng ta console.log(set), kết quả sẽ là {1, 2, 3, 4}. Đây là cách JavaScript hiển thị một Set trong console. Nó sử dụng dấu ngoặc nhọn {} thay vì dấu ngoặc vuông [] như mảng.

1.4. Ví dụ minh họa

Để hiểu rõ hơn, hãy xem xét một ví dụ khác:

const fruits = new Set(['apple', 'banana', 'apple', 'orange', 'banana']);
console.log(fruits); // Output: Set(3) { 'apple', 'banana', 'orange' } // Thêm phần tử vào Set
fruits.add('mango');
fruits.add('apple'); // 'apple' đã tồn tại nên sẽ không được thêm vào console.log(fruits); // Output: Set(4) { 'apple', 'banana', 'orange', 'mango' }

Trong ví dụ này, chúng ta thấy rằng Set tự động loại bỏ các giá trị trùng lặp ('apple' và 'banana'). Khi chúng ta thêm 'mango', nó được thêm vào Set. Tuy nhiên, khi chúng ta cố gắng thêm 'apple' lần nữa, Set vẫn giữ nguyên vì 'apple' đã tồn tại.

1.5. Tóm lại

Set là một cấu trúc dữ liệu hữu ích trong JavaScript khi bạn cần lưu trữ một tập hợp các giá trị duy nhất. Nó tự động xử lý việc loại bỏ các giá trị trùng lặp, giúp code của bạn gọn gàng và hiệu quả hơn trong nhiều trường hợp.

2. Import và Read-only Module

Output của đoạn code bên dưới là gì:

// counter.js
let counter = 10;
export default counter;
// index.js
import myCounter from "./counter"; myCounter += 1; console.log(myCounter);
  • A: 10
  • B: 11
  • C: Error
  • D: NaN
Đáp án của câu hỏi này là ↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
Đáp án: C

Cùng mình đi tìm hiểu tại sao kết quả lại là như vậy nhé ❓️

2.1. Module trong JavaScript

Modules là một tính năng quan trọng trong JavaScript hiện đại, cho phép chúng ta chia nhỏ code thành các phần riêng biệt, dễ quản lý và tái sử dụng. Tuy nhiên, cách modules hoạt động có một số đặc điểm quan trọng mà chúng ta cần lưu ý.

2.2. Import và Read-only

Khi chúng ta import một giá trị từ một module khác, giá trị đó được coi là read-only (chỉ đọc). Điều này có nghĩa là chúng ta không thể trực tiếp thay đổi giá trị đã import.

Trong ví dụ của chúng ta:

// counter.js
let counter = 10;
export default counter;
// index.js
import myCounter from "./counter"; myCounter += 1; // Lỗi! console.log(myCounter);

Khi chúng ta cố gắng thay đổi giá trị của myCounter, JavaScript sẽ throw một Error. Cụ thể, nó sẽ là một TypeError với thông báo như "Assignment to constant variable" hoặc tương tự.

2.3. Tại sao lại như vậy?

Đây là một tính năng bảo vệ trong hệ thống module của JavaScript. Nó ngăn chặn các module khác vô tình hoặc cố ý thay đổi trạng thái của module được import, giúp đảm bảo tính nhất quán và dễ dự đoán của code.

2.4. Làm thế nào để thay đổi giá trị?

Nếu bạn muốn thay đổi giá trị của một biến được export, bạn nên export một function để thay đổi giá trị đó. Ví dụ:

// counter.js
let counter = 10; export function incrementCounter() { counter += 1; return counter;
} export default counter;
// index.js
import myCounter, { incrementCounter } from "./counter"; console.log(myCounter); // 10
console.log(incrementCounter()); // 11
console.log(myCounter); // Vẫn là 10!

Trong ví dụ này, myCounter vẫn giữ nguyên giá trị ban đầu, nhưng chúng ta có thể thay đổi giá trị của counter trong module gốc thông qua function incrementCounter.

2.5. Tóm lại

Hiểu về tính chất read-only của các giá trị được import là rất quan trọng khi làm việc với modules trong JavaScript. Nó giúp chúng ta tránh được nhiều lỗi tiềm ẩn và viết code an toàn, dễ bảo trì hơn. Khi cần thay đổi giá trị từ một module khác, hãy nhớ sử dụng các function được export thay vì cố gắng thay đổi trực tiếp giá trị đã import.

3. Phép toán delete trong JavaScript

Output của đoạn code bên dưới là gì:

const name = "Lydia";
age = 21; console.log(delete name);
console.log(delete age);
  • A: false, true
  • B: "Lydia", 21
  • C: true, true
  • D: undefined, undefined
Đáp án của câu hỏi này là ↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
Đáp án: A

Cùng mình đi tìm hiểu tại sao kết quả lại là như vậy nhé ❓️

3.1. Phép toán delete trong JavaScript

Phép toán delete trong JavaScript được sử dụng để xóa một thuộc tính khỏi một đối tượng. Điều quan trọng cần nhớ là:

  1. delete trả về true nếu xóa thành công hoặc nếu thuộc tính không tồn tại.
  2. delete trả về false nếu không thể xóa thuộc tính (ví dụ: thuộc tính không thể xóa được).
  3. delete không ảnh hưởng đến các biến được khai báo bằng var, let, hoặc const.

3.2. Phân tích đoạn code

Trong đoạn code của chúng ta:

const name = "Lydia";
age = 21; console.log(delete name);
console.log(delete age);

3.2.1. Trường hợp của name

name được khai báo bằng const, do đó nó không thể bị xóa bởi phép toán delete. Vì vậy, delete name sẽ trả về false.

3.2.2. Trường hợp của age

age được khai báo mà không sử dụng var, let, hoặc const. Trong trường hợp này, JavaScript sẽ tự động tạo một thuộc tính trên đối tượng toàn cục (global object). Trong môi trường trình duyệt, đối tượng toàn cục là window.

age là một thuộc tính của đối tượng toàn cục, nó có thể bị xóa bởi phép toán delete. Do đó, delete age sẽ trả về true.

3.3. Ví dụ minh họa

Để hiểu rõ hơn, hãy xem xét ví dụ sau:

const obj = {x: 1, y: 2};
let z = 3; console.log(delete obj.x); // true
console.log(delete obj.y); // true
console.log(delete z); // false console.log(obj); // {}, z vẫn là 3

Trong ví dụ này:

  • delete obj.xdelete obj.y trả về true vì chúng xóa thành công các thuộc tính của đối tượng.
  • delete z trả về falsez là một biến được khai báo bằng let, không thể bị xóa bởi delete.

3.4. Tóm lại

Phép toán delete trong JavaScript chỉ có tác dụng với các thuộc tính của đối tượng. Nó không thể xóa các biến được khai báo bằng var, let, hoặc const. Khi sử dụng delete, hãy nhớ rằng nó trả về giá trị boolean chỉ ra liệu việc xóa có thành công hay không, chứ không phải giá trị của thuộc tính bị xóa.

4. Destructuring trong JavaScript

Output của đoạn code bên dưới là gì:

const numbers = [1, 2, 3, 4, 5];
const [y] = numbers; console.log(y);
  • A: [[1, 2, 3, 4, 5]]
  • B: [1, 2, 3, 4, 5]
  • C: 1
  • D: [1]
Đáp án của câu hỏi này là ↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
Đáp án: C

Cùng mình đi tìm hiểu tại sao kết quả lại là như vậy nhé ❓️

4.1. Destructuring trong JavaScript

Destructuring là một cú pháp trong JavaScript cho phép chúng ta "giải nén" các giá trị từ mảng hoặc thuộc tính từ đối tượng vào các biến riêng biệt. Đây là một tính năng mạnh mẽ giúp code trở nên ngắn gọn và dễ đọc hơn.

4.2. Array Destructuring

Trong trường hợp của chúng ta, chúng ta đang sử dụng array destructuring:

const numbers = [1, 2, 3, 4, 5];
const [y] = numbers;

Cú pháp [y] ở đây có nghĩa là:

  • Lấy phần tử đầu tiên của mảng numbers và gán nó cho biến y.

4.3. Phân tích kết quả

y được gán giá trị của phần tử đầu tiên trong mảng numbers, nên y sẽ có giá trị là 1.

Khi chúng ta console.log(y), kết quả sẽ là 1.

4.4. Ví dụ mở rộng

Để hiểu rõ hơn về array destructuring, hãy xem xét một vài ví dụ khác:

const colors = ['red', 'green', 'blue']; // Lấy phần tử đầu tiên
const [firstColor] = colors;
console.log(firstColor); // 'red' // Lấy phần tử thứ hai và thứ ba
const [, secondColor, thirdColor] = colors;
console.log(secondColor, thirdColor); // 'green' 'blue' // Sử dụng rest operator
const [primary, ...secondaryColors] = colors;
console.log(primary); // 'red'
console.log(secondaryColors); // ['green', 'blue']

4.5. Tóm lại

Array destructuring là một cách tiện lợi để trích xuất giá trị từ mảng trong JavaScript. Nó cho phép chúng ta gán các giá trị của mảng vào các biến một cách nhanh chóng và dễ đọc. Trong ví dụ của chúng ta, [y] lấy phần tử đầu tiên của mảng numbers, do đó y có giá trị là 1.

5. Spread Operator trong JavaScript

Output của đoạn code bên dưới là gì:

const user = { name: "Lydia", age: 21 };
const admin = { admin: true, ...user }; console.log(admin);
  • A: { admin: true, user: { name: "Lydia", age: 21 } }
  • B: { admin: true, name: "Lydia", age: 21 }
  • C: { admin: true, user: ["Lydia", 21] }
  • D: { admin: true }
Đáp án của câu hỏi này là ↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
↓↓↓↓↓↓↓↓↓↓
Đáp án: B

Cùng mình đi tìm hiểu tại sao kết quả lại là như vậy nhé ❓️

5.1. Spread Operator trong JavaScript

Spread Operator (...) là một tính năng mạnh mẽ trong JavaScript, được giới thiệu từ ES6. Nó cho phép chúng ta "trải" (spread) các phần tử của một đối tượng có thể lặp lại (như mảng hoặc đối tượng) thành các phần tử riêng lẻ.

5.2. Sử dụng Spread Operator với Objects

Khi sử dụng Spread Operator với objects, nó sẽ sao chép tất cả các cặp key-value của object đó vào object mới.

Trong trường hợp của chúng ta:

const user = { name: "Lydia", age: 21 };
const admin = { admin: true, ...user };

Spread Operator ...user sẽ "trải" tất cả các thuộc tính của user vào object admin.

5.3. Phân tích kết quả

Kết quả của console.log(admin) sẽ là:

{ admin: true, name: "Lydia", age: 21 }

Điều này xảy ra vì:

  1. admin: true được thêm vào object admin.
  2. ...user "trải" các thuộc tính của user (nameage) vào object admin.

5.4. Ví dụ mở rộng

Để hiểu rõ hơn về Spread Operator với objects, hãy xem xét một vài ví dụ khác:

// Kết hợp nhiều objects
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };
const combined = { ...obj1, ...obj2 };
console.log(combined); // { a: 1, b: 2, c: 3, d: 4 } // Ghi đè thuộc tính
const defaultSettings = { theme: 'light', fontSize: 12 };
const userSettings = { ...defaultSettings, theme: 'dark' };
console.log(userSettings); // { theme: 'dark', fontSize: 12 } // Thêm thuộc tính mới
const base = { x: 10, y: 20 };
const extended = { ...base, z: 30 };
console.log(extended); // { x: 10, y: 20, z: 30 }

5.5. Tóm lại

Spread Operator là một công cụ mạnh mẽ trong JavaScript để làm việc với objects và arrays. Khi sử dụng với objects, nó cho phép chúng ta dễ dàng sao chép và kết hợp các thuộc tính từ nhiều objects khác nhau. Trong ví dụ của chúng ta, nó giúp tạo ra một object mới admin bao gồm cả thuộc tính admin: true và tất cả các thuộc tính của object user.

Nếu có bất kỳ câu hỏi nào đừng ngại hãy bình luận dưới phần comment nhé. Hoặc chỉ cần để lại một comment chào mình là đã giúp mình có thêm động lực hoàn thành series này. Cảm ơn các bạn rất nhiều. 🤗

Bình luận

Bài viết tương tự

- vừa được xem lúc

Giới thiệu Typescript - Sự khác nhau giữa Typescript và Javascript

Typescript là gì. TypeScript là một ngôn ngữ giúp cung cấp quy mô lớn hơn so với JavaScript.

0 0 518

- vừa được xem lúc

Bạn đã biết các tips này khi làm việc với chuỗi trong JavaScript chưa ?

Hi xin chào các bạn, tiếp tục chuỗi chủ đề về cái thằng JavaScript này, hôm nay mình sẽ giới thiệu cho các bạn một số thủ thuật hay ho khi làm việc với chuỗi trong JavaScript có thể bạn đã hoặc chưa từng dùng. Cụ thể như nào thì hãy cùng mình tìm hiểu trong bài viết này nhé (go).

0 0 429

- vừa được xem lúc

Một số phương thức với object trong Javascript

Trong Javascript có hỗ trợ các loại dữ liệu cơ bản là giống với hầu hết những ngôn ngữ lập trình khác. Bài viết này mình sẽ giới thiệu về Object và một số phương thức thường dùng với nó.

0 0 147

- vừa được xem lúc

Tìm hiểu về thư viện axios

Giới thiệu. Axios là gì? Axios là một thư viện HTTP Client dựa trên Promise.

0 0 135

- vừa được xem lúc

Imports và Exports trong JavaScript ES6

. Giới thiệu. ES6 cung cấp cho chúng ta import (nhập), export (xuất) các functions, biến từ module này sang module khác và sử dụng nó trong các file khác.

0 0 105

- vừa được xem lúc

Bài toán đọc số thành chữ (phần 2) - Hoàn chỉnh chương trình dưới 100 dòng code

Tiếp tục bài viết còn dang dở ở phần trước Phân tích bài toán đọc số thành chữ (phần 1) - Phân tích đề và những mảnh ghép đầu tiên. Bạn nào chưa đọc thì có thể xem ở link trên trước nhé.

0 0 241