Ép buộc là một chuyển đổi loại tự động xảy ra trong JavaScript khi bạn muốn thực hiện một số thao tác nhất định. Tôi sẽ giải thích sự ép buộc là gì trong bài viết này.
Chuyển đổi loại là gì?
Như tên ngụ ý, chuyển đổi loại là quá trình chuyển đổi một giá trị từ loại này sang loại khác.
Các giá trị trong JavaScript có thể thuộc các loại khác nhau. Bạn có thể có một số, chuỗi, đối tượng, boolean – bạn đặt tên cho nó. Đôi khi, bạn có thể muốn chuyển đổi dữ liệu từ loại này sang loại khác để phù hợp với một hoạt động nhất định.
Chuyển đổi loại có thể là ẩn (được thực hiện tự động trong quá trình thực thi mã) hoặc rõ ràng (do nhà phát triển của bạn thực hiện).
Chuyển đổi loại ngầm định còn được biết đến (và thường được gọi nhiều hơn) là ép buộc trong khi Chuyển đổi loại rõ ràng còn được gọi là loại đúc. Hãy xem xét hai chuyển đổi này một cách chi tiết.
Tôi cũng có một phiên bản video của hướng dẫn này nếu bạn muốn.
Chuyển đổi loại ngầm định (Ép buộc) là gì?
Có một số thao tác mà bạn có thể thử thực hiện trong JavaScript mà thực sự là không thể thực hiện được. Ví dụ: hãy xem đoạn mã sau:
const sum = 35 + "hello"
Ở đây, bạn đang cố thêm một số và một chuỗi. Điều này, thực tế mà nói, là không thể. Bạn chỉ có thể thêm số (Tổng) với nhau hoặc thêm chuỗi (nối liền) cùng với nhau.
Vậy điều gì xảy ra ở đây nếu bạn cố chạy mã?
Chà, JavaScript là một ngôn ngữ được đánh máy yếu. Thay vì JavaScript đưa ra một lỗi, nó buộc loại của một giá trị phải khớp với loại của giá trị kia để có thể thực hiện thao tác.
Trong trường hợp này, sử dụng + ký bằng một số và một chuỗi, số được buộc thành một chuỗi, sau đó + dấu hiệu được sử dụng cho một hoạt động nối.
const sum = 35 + "hello"
console.log(sum)
// 35hello
console.log(typeof sum)
// string
Đây là một ví dụ về ép buộc trong đó loại của một giá trị bị ép buộc phải khớp với giá trị kia để hoạt động có thể tiếp tục.
Với dấu cộng, lý tưởng hơn là số được chuyển thành chuỗi (thay vì chuỗi được chuyển thành số). Điều này là do một số tương đương với một chuỗi là NaN
nhưng một chuỗi tương đương với một số, giả sử 15
Là "15"
– vì vậy nó có ý nghĩa hơn để nối liền hai chuỗi so với Tổng một số và NaN
.
Nhìn vào một ví dụ khác dưới đây:
const times = 35 * "hello"
console.log(times)
// NaN
Ở đây, chúng tôi sử dụng thời gian * cho một số và một chuỗi. Không có phép toán nào với các chuỗi liên quan đến phép nhân, vì vậy ở đây, phép cưỡng chế lý tưởng là từ chuỗi này sang số khác (vì các số có các phép toán tương thích với phép nhân).
Nhưng vì một chuỗi (trong trường hợp này, "hello"
) được chuyển đổi thành một số (là NaN
) và số đó được nhân với 35
kết quả cuối cùng là NaN
.
Ép buộc thường được gây ra bởi các toán tử khác nhau được sử dụng giữa các loại dữ liệu khác nhau:
const string = ""
const number = 40
const boolean = true
console.log(!string)
// true - string is coerced to boolean `false`, then the NOT operator negates it
console.log(boolean + string)
// "true" - boolean is coerced to string "true", and concatenated with the empty string
console.log(40 + true)
// 41 - boolean is coerced to number 1, and summed with 40
Một toán tử rất phổ biến gây ra sự ép buộc là toán tử bình đẳng lỏng lẻo (==hoặc gấp đôi bằng).
Bình đẳng đôi và ép buộc
Trong JavaScript, có cả toán tử đẳng thức kép (== được gọi là toán tử bình đẳng lỏng lẻo) và toán tử đẳng thức ba (=== được gọi là toán tử bình đẳng nghiêm ngặt). Bạn sử dụng cả hai toán tử để so sánh sự bằng nhau của các giá trị.
Cách hoạt động của toán tử bình đẳng lỏng lẻo
Các toán tử bình đẳng lỏng lẻo kiểm tra lỏng lẻo. Nó kiểm tra xem các giá trị có bằng nhau không. Các loại không phải là trọng tâm của toán tử này – chỉ các giá trị là yếu tố chính.
Điều tôi muốn nói ở đây là 20giá trị của a number
loại, và “20”một giá trị của string
loại, bằng nhau khi bạn sử dụng đẳng thức kép:
const variable1 = 20
const variable2 = "20"
console.log(variable1 == variable2)
// true
Mặc dù các loại không bằng nhau, toán tử trả về true
vì các giá trị bằng nhau. Điều xảy ra ở đây là ép buộc.
Khi bạn sử dụng toán tử bình đẳng lỏng lẻo với các giá trị thuộc các loại khác nhau, điều xảy ra đầu tiên là sự ép buộc. Một lần nữa, đây là nơi một giá trị được chuyển đổi thành loại phù hợp với giá trị kia, trước khi so sánh xảy ra.
Trong trường hợp này, các chuỗi “20” được chuyển đổi thành một loại số (đó là 20
) rồi so sánh với giá trị kia và cả hai đều bằng nhau.
Một vi dụ khac:
const variable1 = false
const variable2 = ""
console.log(variable1 == variable2)
// true
Đây, variable1
là giá trị sai (kiểu boolean) và variable2
là giá trị “” (một chuỗi rỗng, thuộc loại string). So sánh cả hai biến với trả về đẳng thức kép true
. Đó là bởi vì chuỗi trống bị ép thành kiểu boolean (tức là sai).
Cách hoạt động của toán tử bình đẳng nghiêm ngặt
Toán tử này thực hiện kiểm tra nghiêm ngặt – nghĩa là nó kiểm tra nghiêm ngặt các giá trị được so sánh cũng như các loại. Loại ép buộc không xảy ra ở đây, vì vậy không có câu trả lời bất ngờ. Dưới đây là các ví dụ từ trên:
const variable1 = 20
const variable2 = "20"
console.log(variable1 === variable2)
// false
const variable3 = false
const variable4 = ""
console.log(variable3 === variable4)
// false
Trong trường hợp variable1
và variable2
, chúng có cùng giá trị, nhưng kiểu không giống nhau. Vậy đẳng thức ba trả về false
.
Trong trường hợp variable3
và variable4
chúng có cùng giá trị (nếu cái này được chuyển đổi thành loại của cái kia) nhưng các loại không giống nhau, do đó trả về đẳng thức ba false
lần này cũng vậy.
Chuyển đổi kiểu rõ ràng (Đúc kiểu) là gì?
Ở đây, bạn chuyển đổi rõ ràng một giá trị từ loại này sang loại khác. Điều này cũng có thể là để bạn thực hiện thành công một thao tác nào đó.
Để chuyển đổi rõ ràng các loại, bạn sử dụng loại Constructors
. Ví dụ: để chuyển đổi một số thành một chuỗi:
const number = 30
const numberConvert = String(number)
console.log(numberConvert)
// "30"
console.log(typeof numberConvert)
// string
Một ví dụ khác là chuyển đổi một số thành boolean:
const number = 30
const numberConvert = Boolean(number)
console.log(numberConvert)
// true
console.log(typeof numberConvert)
// boolean
Và một ví dụ nữa, để chuyển đổi boolean thành chuỗi:
const boolean = false
const booleanConvert = String(boolean)
console.log(booleanConvert)
// "false"
console.log(typeof booleanConvert)
// string
Trong các ví dụ này, chúng tôi chuyển đổi rõ ràng một giá trị từ loại này sang loại khác. Những trường hợp mà bạn cần phải làm điều này là gì?
Điều này rất hữu ích khi bạn không biết mình đang mong đợi loại giá trị nào. Ví dụ: dữ liệu đến từ API. Giả sử một API được định cấu hình để trả về một chuỗi, có thể là “50” và bạn muốn so sánh nó với một số bằng cách sử dụng đẳng thức nghiêm ngặt như sau:
const apiData = {
rate: "50"
}
console.log(apiData.rate === 50)
// false
Trong trường hợp như vậy, trước tiên bạn muốn đảm bảo rằng giá trị là một loại số một cách rõ ràng (thay vì dựa vào đẳng thức kép để kích hoạt tính cưỡng chế) trước khi thực hiện kiểm tra:
const apiData = {
rate: "50"
}
const rate = Number(apiData.rate)
console.log(rate === 50)
// true
kết thúc
Bởi vì JavaScript là một ngôn ngữ được gõ yếu, đôi khi bạn có thể có những chuyển đổi loại không mong muốn. Điều này hoàn toàn xảy ra khi bạn cố gắng sử dụng một số toán tử giữa các giá trị thuộc các kiểu khác nhau. Sau đó, thay vì gặp lỗi, JavaScript sẽ cố gắng “giúp đỡ” bạn. JavaScript giống như …
“Ồ, tôi nghĩ họ muốn nhập một chuỗi nhưng thay vào đó họ đã nhập một số. Hãy giúp họ chuyển đổi nó thành một chuỗi trước khi chúng ta thực hiện thao tác. Họ sẽ đánh giá cao điều đó 😇”
Chà, không thực sự như thế này 😂 nhưng tôi hy vọng bạn hiểu ý.
Trong bài viết này, chúng ta đã xem cách chuyển đổi loại hoạt động trong JavaScript – cả ngầm định và rõ ràng – với các ví dụ.
Mặc dù sự ép buộc đôi khi có thể hữu ích, nhưng nó có thể gây ra các lỗi không mong muốn, đặc biệt là khi so sánh các giá trị với toán tử bình đẳng lỏng lẻo. Đó là lý do tại sao nên luôn luôn sử dụng toán tử bình đẳng nghiêm ngặt để so sánh các giá trị.
Ngoài ra, việc sử dụng TypeScript có thể giúp bạn tránh các lỗi không lường trước được vì bạn có thể đảm bảo rằng các biến là kiểu dữ liệu mà bạn muốn.