Ép kiểu ẩn trong javascript

Ép buộc loại là một trong những câu hỏi phỏng vấn được hỏi nhiều nhất về JavaScript, hoàn toàn dựa trên khái niệm. Để giải quyết các vấn đề về ép buộc kiểu, người ta phải hiểu các quy tắc và phương pháp ép buộc kiểu trong JavaScript. Có nhiều loại dữ liệu như chuỗi, số, boolean, v.v. Vì vậy, điều rất quan trọng là phải biết cách các loại dữ liệu này bị ép buộc từ loại dữ liệu này sang loại dữ liệu khác. Vui lòng đọc hết bài viết này để hiểu rõ hơn về khái niệm này

Phạm vi

  • Trong bài viết này, việc ép kiểu trong JavaScript được giải thích với sự trợ giúp của nhiều ví dụ khác nhau
  • Ghi chú. Các chức năng chuyển đổi loại nội bộ và thuật toán cưỡng chế không được thảo luận ở đây

Loại ép buộc trong JavaScript là gì?

Trước khi hiểu về ép kiểu trong JavaScript, hãy tham khảo ví dụ dưới đây,

const val_1 = "10";
const val_2 = 10;
let total = val_1 - val_2;

console.log(total);

Bạn nghĩ kết quả của biến 'total' ở trên sẽ là bao nhiêu? . Mặc dù val_1 thuộc kiểu dữ liệu chuỗi và val_2 thuộc kiểu dữ liệu số nhưng chúng ta nhận được kết quả là 0 vì JavaScript đã chuyển đổi val_1 từ chuỗi thành số trước khi thực hiện phép trừ, đây là kiểu ép buộc trong JavaScript. Bây giờ hãy quan sát ví dụ dưới đây, nơi chúng tôi đang thêm cả hai biến thay vì trừ chúng

const val_1 = "10";
const val_2 = 10;
let total = val_1 + val_2;

console.log(total);

Vì vậy, bây giờ, bạn nghĩ kết quả của tổng biến trên sẽ là gì? . Tại đây bạn sẽ nhận được một kết quả không thể đoán trước đó là 1010 i. e, một chuỗi. Nhưng tại sao? . Vì vậy, không có gì khó chịu, chúng ta hãy tìm hiểu sâu hơn về ép buộc kiểu trong JavaScript và hiểu cách thức hoạt động của nó

Như bạn đã thấy trong các ví dụ trên, quá trình chuyển đổi giá trị từ một loại dữ liệu này sang một loại dữ liệu khác, chẳng hạn như chuyển đổi một loại dữ liệu số thành một loại dữ liệu chuỗi, được gọi là Loại ép buộc trong JavaScript. Có thể thấy sự ép buộc kiểu khi các phép tính số học và so sánh khác nhau được thực hiện trên các kiểu dữ liệu khác nhau trong JavaScript. Có hai loại Type Coercion trong JavaScript. Tiềm ẩn và rõ ràng

Ép buộc tiềm ẩn VS rõ ràng trong JavaScript

ép kiểu ngầm định. Từ đồng nghĩa của từ 'ngầm' là 'gián tiếp'. Do đó, như từ gợi ý, ép buộc kiểu ẩn trong JavaScript đề cập đến việc chuyển đổi các giá trị từ một loại dữ liệu sang một loại dữ liệu khác mà không có sự can thiệp của nhà phát triển hoặc ép buộc kiểu xảy ra gián tiếp. Nói một cách đơn giản, chúng ta có thể nói rằng việc ép buộc kiểu ẩn được thực hiện tự động bởi chính javascript

ví dụ

let myVar = 10 + '10';
console.log(myVar); // returns "1010"

Trong ví dụ trên, bạn có thể thấy rằng myVar trả về 1010 dưới dạng một chuỗi thay vì giá trị bổ sung20. Điều này là do sự ép buộc kiểu ẩn trong JavaScript trong đó kiểu dữ liệu số 10 được chuyển đổi hoàn toàn thành kiểu dữ liệu chuỗi và sau đó do nối chuỗi, 1010(một chuỗi) được trả về thay vì 20(một số)

ép buộc kiểu rõ ràng. Từ đồng nghĩa của từ 'rõ ràng' là 'trực tiếp'. Do đó, như từ gợi ý, ép buộc kiểu rõ ràng trong JavaScript đề cập đến việc chuyển đổi các giá trị từ một loại dữ liệu này sang một loại dữ liệu khác với sự can thiệp của nhà phát triển hoặc kiểu ép buộc xảy ra trực tiếp. Nói một cách đơn giản, chúng ta có thể nói rằng việc cưỡng chế loại Rõ ràng được thực hiện bởi chính nhà phát triển và không xảy ra tự động

ví dụ

let myVar = String(10);
console.log(myVar);

Trong ví dụ trên, bạn có thể thấy rằng myVar trả về 10 dưới dạng một chuỗi. Điều này là do sự ép buộc kiểu rõ ràng trong JavaScript trong đó kiểu dữ liệu số 10 được chuyển đổi thành kiểu dữ liệu chuỗi một cách rõ ràng

Các loại chuyển đổi trong JavaScript

Có ba loại chuyển đổi trong JavaScript có thể được sử dụng để chuyển đổi các giá trị từ một loại dữ liệu này sang một loại dữ liệu khác bằng cách ép buộc kiểu ẩn cũng như rõ ràng. Hành vi của JavaScript trong quá trình ép kiểu là khác nhau đối với nguyên thủy và đối tượng. Do đó, đầu tiên chúng ta sẽ xem các nguyên hàm và sau đó, chúng ta sẽ xem nó cho các đối tượng trong JavaScript

thành chuỗi

ép kiểu ngầm định. Nếu bất kỳ giá trị kiểu dữ liệu chuỗi nào được nối (sử dụng toán tử + số học) với kiểu dữ liệu 'khác', thì kiểu dữ liệu 'khác' đó được chuyển đổi hoàn toàn thành chuỗi. ví dụ

let myVar_1 = 10 + ''; 
console.log(myVar_1); // returned 10 as a String

let myVar_2 = 10.5 + '';
console.log(myVar_2); // returned 10.5 as a String

let myVar_3 = -10.5 + '';
console.log(myVar_3); // returned -10.5 as a String

let myVar_4 = true + '';
console.log(myVar_4); // returned true as a String

Giải trình

  1. Trong myVar_1, myVar_2 và myVar_3 ở trên, kiểu dữ liệu số được chuyển đổi hoàn toàn thành kiểu dữ liệu chuỗi do nối với chuỗi
  2. Tương tự, trong myVar_4, kiểu dữ liệu boolean được chuyển đổi hoàn toàn thành kiểu dữ liệu chuỗi do nối với chuỗi

ép buộc kiểu rõ ràng. Chúng ta có thể sử dụng hàm String() do JavaScript cung cấp để chuyển đổi bất kỳ kiểu dữ liệu nào khác thành kiểu dữ liệu chuỗi

ví dụ

let myVar_1 = String(45);	
console.log(myVar_1);		// returns '45' as a String

let myVar_2 = String(-45.22);	
console.log(myVar_2);		// returns '-45.22' as a String

let myVar_3= String(true);	
console.log(myVar_3);		// returns 'true' as a String

let myVar_4 = String(false);	
console.log(myVar_4);		// returns 'false' as a String

let myVar_5 = String(null);	
console.log(myVar_5);		// returns 'null' as a String

let myVar_6 = String(undefined);
console.log(myVar_6);		// returns 'undefined' as a String

Giải trình

  1. Trong biến myVar_1 , một số dương được chuyển đổi thành giá trị Chuỗi. Do đó, 45 được trả về dưới dạng Chuỗi
  2. Trong biến myVar_2 , một số âm được chuyển đổi thành giá trị Chuỗi. Do đó, -45. 22 được trả về dưới dạng Chuỗi
  3. Trong biến myVar_3 và myVar_4 , giá trị boolean được chuyển đổi thành giá trị Chuỗi. Do đó, true và false được trả về dưới dạng Chuỗi
  4. Trong biến myVar_5 , null được chuyển đổi thành giá trị Chuỗi. Do đó, null được trả về dưới dạng Chuỗi
  5. Trong biến myVar_6 , undefined được chuyển đổi thành giá trị Chuỗi. Do đó, không xác định được trả về dưới dạng Chuỗi

để boolean

ép kiểu ngầm định. Khi ngữ cảnh lô-gic xuất hiện hoặc các phép toán lô-gic được thực hiện bởi các toán tử lô-gic, việc ép kiểu đối với kiểu dữ liệu boolean xảy ra hoàn toàn

Thí dụ

if(4){
    console.log("I am true");
}else{
    console.log("I am false");
}

Trong ví dụ trên, do bối cảnh logic, tôi đúng được trả về trong bảng điều khiển do ép buộc kiểu ẩn đối với kiểu dữ liệu boolean

ép buộc kiểu rõ ràng. Chúng ta có thể sử dụng hàm Boolean() do JavaScript cung cấp để chuyển đổi bất kỳ loại dữ liệu nào khác thành loại dữ liệu boolean

ví dụ

let myVal1 = Boolean(0);
console.log(myVal1) // returns false

let myVal2 = Boolean('');
console.log(myVal2) // returns false

let myVal3 = Boolean(NaN);  
console.log(myVal3) // returns false

let myVal4 = Boolean(false); 
console.log(myVal4) // returns false

let myVal5 = Boolean(undefined);
console.log(myVal5) // returns false

let myVal6 = Boolean(null);
console.log(myVal6) // returns false

let myVal7 = Boolean(23);
console.log(myVal7) // returns true

let myVal8 = Boolean(-23);
console.log(myVal8) // returns true

let myVal9 = Boolean(23.51);
console.log(myVal9) // returns true

Trong các ví dụ đã cho ở trên, bạn có thể nhận thấy rằng khi chúng ta chuyển đổi 0, '' (một chuỗi rỗng), NaN, false, undefined và null, false được trả về trong bảng điều khiển. Đối với mọi giá trị trống như một mảng trống, đối tượng, v.v. true được trả về ngoại trừ một chuỗi rỗng. Tham khảo ví dụ dưới đây

________số 8_______

Đến số

ép kiểu ngầm định. Trong khi xử lý các loại dữ liệu khác có số bằng toán tử so sánh, toán tử số học, toán tử bit và toán tử đẳng thức không nghiêm ngặt (==), các loại dữ liệu khác được chuyển đổi hoàn toàn thành số

ví dụ

let a1 = +'10'     
console.log(a1); // returns 10 as a number

let a2 = true | 0   
console.log(a2); // returns 1 as a number

let a3 = 10 == '5'
console.log(a3); // returns false.

let a4 = 4 < '6'   
console.log(a4); // returns  true

let a5 = 10 + '10';
console.log(a5); // returns '1010' as a string.
  1. Trong biến a1, 10 được trả về dưới dạng một số do ép buộc kiểu ẩn
  2. Trong biến a2, true được chuyển đổi hoàn toàn thành 1 dưới dạng một số;
  3. Trong biến a3, kiểu dữ liệu chuỗi 5 được chuyển đổi thành kiểu dữ liệu số 5 trước khi so sánh đẳng thức hoàn toàn do toán tử đẳng thức không nghiêm ngặt (==), do đó trả về false vì 5 không bằng 10
  4. Trong biến a4, kiểu dữ liệu chuỗi 6 được chuyển đổi hoàn toàn thành kiểu dữ liệu số 6 trước khi so sánh các giá trị, do đó giá trị true được trả về là 4 nhỏ hơn 6 về giá trị
  5. Trong biến a5, chúng tôi đã thấy một trường hợp đặc biệt khi số 10 cho 1010 dưới dạng chuỗi khi được thêm vào với chuỗi 10 trong khi chúng tôi mong đợi kết quả là 20. Trên thực tế, phép nối đã xảy ra ở đây thay vì phép cộng vì JavaScript ưu tiên phép nối hơn phép cộng khi toán tử + được sử dụng giữa một chuỗi số và một số

ép buộc kiểu rõ ràng. Chúng ta có thể sử dụng hàm Number() do JavaScript cung cấp để chuyển đổi bất kỳ loại dữ liệu nào khác thành loại dữ liệu số

ví dụ

const val_1 = "10";
const val_2 = 10;
let total = val_1 + val_2;

console.log(total);
0
  1. Trong biến a1, kiểu dữ liệu chuỗi 10 được chuyển đổi thành kiểu dữ liệu số 10 một cách rõ ràng bằng cách sử dụng hàm Number()
  2. Trong biến a2, kiểu dữ liệu boolean false được chuyển thành kiểu dữ liệu số 0 (không) một cách rõ ràng bằng cách sử dụng hàm Number()
  3. Trong biến a3, kiểu dữ liệu boolean true được chuyển đổi thành kiểu dữ liệu số 1 (một) rõ ràng bằng cách sử dụng hàm Number()

Chuyển đổi chuỗi thành số

Như chúng ta đã thảo luận ở trên, bất kỳ kiểu dữ liệu nguyên thủy nào cũng có thể được chuyển đổi thành kiểu dữ liệu số bằng cách sử dụng hàm Number() do JavaScript cung cấp. Do đó để chuyển chuỗi sang kiểu dữ liệu số ta có thể sử dụng hàm Number(). Lưu ý rằng hàm Number() chỉ chuyển đổi chuỗi số chứ không chuyển đổi chuỗi chữ cái. Hãy để chúng tôi xem thêm một số ví dụ-

const val_1 = "10";
const val_2 = 10;
let total = val_1 + val_2;

console.log(total);
1

Trong các ví dụ trên, bạn có thể nhận thấy rằng biến myNum1 trả về 15 dưới dạng một số vì 15 là một chuỗi số trong khi biến myVar2 trả về NaN (Không phải là Số) vì hello không phải là một chuỗi số

Chuyển đổi Boolean sang Số

Như chúng ta đã thảo luận ở trên, bất kỳ kiểu dữ liệu nguyên thủy nào cũng có thể được chuyển đổi thành kiểu dữ liệu số bằng cách sử dụng hàm Number() do JavaScript cung cấp. Do đó để chuyển đổi kiểu dữ liệu boolean sang kiểu số, chúng ta có thể sử dụng hàm Number(). Lưu ý rằng hàm Number() chuyển đổi boolean true thành 1 và boolean false thành 0. Hãy để chúng tôi xem thêm một số ví dụ-

const val_1 = "10";
const val_2 = 10;
let total = val_1 + val_2;

console.log(total);
2

Trong các ví dụ trên, bạn có thể nhận thấy rằng biến myNum1 trả về 1 dưới dạng số khi true được chuyển thành 1 trong khi myNum2 trả về 0 dưới dạng số vì false được chuyển thành 0

Toán Tử Bình Đẳng (==)

Toán tử đẳng thức hoặc không nghiêm ngặt cũng dẫn đến ép buộc kiểu ngầm. Nhưng tại sao? . Hãy để chúng tôi xem một số ví dụ-

const val_1 = "10";
const val_2 = 10;
let total = val_1 + val_2;

console.log(total);
3
  1. Trong val_1 và val_2, Chuỗi số được chuyển đổi thành kiểu dữ liệu số ngay trước khi so sánh đẳng thức, do đó nó trả về true cho val_1 và false cho val_2
  2. Trong val_3 và val_4, true được chuyển thành 1 và false được chuyển thành 0 ngay trước khi so sánh đẳng thức, do đó true được trả về trong cả hai trường hợp

Một điều nữa. Trong ví dụ dưới đây, chúng tôi đã gán 3 làm giá trị cho biến num. Khi chúng tôi sử dụng toán tử bằng nhau nghiêm ngặt (===) để kiểm tra xem 3 có bằng đúng hay không, chúng tôi nhận được kết quả sai nhưng đồng thời khi chúng tôi sử dụng num bên trong khối điều kiện của if, chúng tôi nhận được nó đúng như mã bên trong khối if . Nhưng tại sao?

const val_1 = "10";
const val_2 = 10;
let total = val_1 + val_2;

console.log(total);
4

Đó là bởi vì toán tử đẳng thức nghiêm ngặt (===) kiểm tra đẳng thức mà không chuyển đổi các toán hạng thành kiểu dữ liệu giống nhau hoặc chung. Do đó trong bảng điều khiển đầu tiên. log chúng tôi nhận sai vì num thuộc kiểu dữ liệu số trong khi true thuộc kiểu dữ liệu boolean. Nhưng khi chúng ta sử dụng num bên trong khối điều kiện của if, nó trả về true như chúng ta đã thảo luận trước đó rằng mọi số đều được chuyển đổi thành true trừ 0 trong quá trình ép buộc kiểu ẩn thành kiểu dữ liệu boolean. Do đó trong bảng điều khiển thứ hai. log trong phần thân của điều kiện if, chúng tôi nhận được 'kiểm tra' được in trong bảng điều khiển

Quy tắc ép buộc kiểu trong JavaScript

Trong Type ép buộc, có hai quy tắc đặc biệt mà bạn phải luôn ghi nhớ -

  1. Như chúng ta đã thấy toán tử đẳng thức (==) ở trên, chúng ta nhận thấy rằng nó chuyển đổi cả hai toán hạng thành kiểu dữ liệu chung và sau đó thực hiện so sánh đẳng thức, nhưng trong trường hợp null và không xác định, chuyển đổi số hoàn toàn không xảy ra, điều này . Tham khảo các ví dụ dưới đây

const val_1 = "10";
const val_2 = 10;
let total = val_1 + val_2;

console.log(total);
5

Nếu để ý các ví dụ nêu trên, bạn có thể thấy rằng trong biến typeVal_1, null không được chuyển thành 0 trước khi chuyển đổi;

  1. NaN trong JavaScript không bao giờ trả về true khi so sánh với các giá trị khác bằng toán tử đẳng thức. Đáng ngạc nhiên, nó không trả về true ngay cả khi so sánh với chính nó. Tham khảo các ví dụ được đưa ra dưới đây-

const val_1 = "10";
const val_2 = 10;
let total = val_1 + val_2;

console.log(total);
6

Trong các ví dụ trên, bạn có thể thấy rằng NaN trả về false khi so sánh với các toán hạng khác và thậm chí với chính nó khi sử dụng toán tử đẳng thức (==)

Loại cưỡng chế cho các đối tượng

Như chúng ta đã thấy ép buộc kiểu cho các nguyên hàm ở trên, bây giờ chúng ta sẽ xem xét ép buộc kiểu cho các đối tượng trong JavaScript. Ở đây chúng ta cũng sẽ thấy ba loại chuyển đổi là chuỗi, boolean và số. Đối với cưỡng chế kiểu đối tượng, trước hết giá trị đối tượng được chuyển đổi thành giá trị nguyên thủy và sau đó tiến hành thêm đối với cưỡng chế kiểu. Hãy để chúng tôi xem từng người một

Ngay cả đối với các đối tượng, kiểu ép buộc đơn giản và dễ hiểu nhất là kiểu boolean. Tất cả các giá trị không nguyên thủy như đối tượng hoặc mảng được chuyển thành true. Không quan trọng chúng trống hay chứa đầy giá trị, chúng luôn bị ép buộc hoặc chuyển đổi thành true

Trước hết, các Đối tượng được chuyển đổi thành nguyên thủy bằng một trong các phương thức nội bộ trong JavaScript đó là [[ToPrimitive]]. Chúng ta hãy xem triển khai giả của phương thức [[ToPrimitive]]-

Phương thức [[ToPrimitive]] chấp nhận hai đối số. một giá trị đầu vào và một loại chuyển đổi ưa thích. Số hoặc Chuỗi trong đó Loại ưu tiên có thể được chuyển hoặc cũng có thể tránh được vì đây là đối số tùy chọn. Đối tượng đầu vào có hai phương thức. valueOf() và toString(), được sử dụng để chuyển đổi số cũng như chuỗi. Cả hai đối tượng này đều có sẵn cho bất kỳ loại dẫn xuất nào như Mảng, Ngày, v.v. khi chúng được khai báo trên Đối tượng. nguyên mẫu

Thuật toán chuyển đổi hoặc các bước ép kiểu cho các đối tượng là -

  1. Nếu đầu vào đã cho là một giá trị nguyên thủy, hãy trả về nguyên trạng
  2. Nếu đầu vào đã cho không phải là giá trị nguyên thủy thì hãy gọi đầu vào. toString() và nếu kết quả trở thành nguyên thủy thì trả về kết quả
  3. Nếu đầu vào đã cho vẫn không phải là giá trị nguyên thủy thì hãy gọi đầu vào. valueOf() và nếu kết quả trở thành nguyên thủy thì trả về kết quả
  4. Trong trường hợp nếu cả hai phương thức không chuyển đổi đối tượng thành nguyên thủy thì chỉ cần trả về TypeError

Trong quá trình chuyển đổi số, phương thức valueOf() được gọi trước và phương thức toString() được gọi sau nếu cần, trong khi trong quá trình chuyển đổi Chuỗi, trước tiên, lệnh gọi được thực hiện với phương thức toString() và sau đó phương thức valueOf() được gọi . Vì hầu hết các kiểu dựng sẵn trong JavaScript không có phương thức valueOf(), trong quá trình chuyển đổi số cũng như chuỗi, chỉ phương thức toString() mới có thể được gọi

Thí dụ

const val_1 = "10";
const val_2 = 10;
let total = val_1 + val_2;

console.log(total);
7

Trong ví dụ trên, chúng ta có thể thấy rằng việc thêm biến num và đối tượng myContainer được trả về là 20, điều này là chính xác. Đó là do phương thức valueOf() trong đối tượng 'myContainer' đã trả về 8. Trong trường hợp giá trị của phương thức không có trong đối tượng, NaN được trả về

Biểu tượng ES6. toPrimitive Method

Tính năng ép kiểu mới nhất trong JavaScript là biểu tượng Biểu tượng. toPrimitive, đây là một tính năng ES6 có thể được sử dụng như một phương thức đối tượng. Điểm đặc biệt của phương pháp này là nó cung cấp một giao diện chung để chuyển đổi một đối tượng thành một đối tượng nguyên thủy. Biểu tượng. phương thức toPrimitive có thể ghi đè phương thức toString() và phương thức valueOf(). Điều này đơn giản có nghĩa là Biểu tượng. phương pháp toPrimitive sẽ được xem xét ngay cả khi cả hai phương pháp khác cũng có mặt. Khi ký hiệu. phương thức toPrimitive chạy, nó chấp nhận một đối số gợi ý duy nhất có thể có bất kỳ giá trị nào trong số này. số, chuỗi hoặc mặc định theo tình huống

const val_1 = "10";
const val_2 = 10;
let total = val_1 + val_2;

console.log(total);
8

Biểu tượng. phương thức toPrimitive ghi đè cả hai phương thức toString() và valueOf() ngay cả khi cả hai đều có mặt hoặc được cung cấp

cưỡng chế kiểu ngầm định là gì?

Cưỡng chế loại là chuyển đổi tự động hoặc ngầm định các giá trị từ loại dữ liệu này sang loại dữ liệu khác (chẳng hạn như chuỗi thành số).

Ép buộc ngầm trong JS là gì?

Việc ép buộc ngầm xảy ra khi JavaScript ép buộc loại giá trị thành loại dự kiến . Kiểu ép buộc này xảy ra mà nhà phát triển không nhận thấy.

Loại ẩn trong JavaScript là gì?

Chuyển đổi ngầm định xảy ra khi trình biên dịch (đối với ngôn ngữ được biên dịch) hoặc thời gian chạy (đối với ngôn ngữ tập lệnh như JavaScript) tự động chuyển đổi loại dữ liệu . Mã nguồn cũng có thể yêu cầu chuyển đổi diễn ra một cách rõ ràng.

Trong những trường hợp nào thì có thể chấp nhận sử dụng kiểu ép buộc ngầm định?

Trong trường hợp nào thì có thể chấp nhận sử dụng kiểu ép buộc ngầm định? . To test a "falsy" or "truth" variable value in an if conditional expression.

Ví dụ về ép buộc kiểu là gì?

Cưỡng chế kiểu là việc chuyển đổi một loại đối tượng thành một đối tượng khác thuộc loại khác có nội dung tương tự . Tấm thảm thường xuyên phải ép buộc các đối tượng từ loại này sang loại khác. Một ví dụ phổ biến là sự ép buộc chuỗi "5" thành số nguyên 5 hoặc số 5 kép. 0.

Các loại cưỡng chế là gì?

Cưỡng chế loại có thể rõ ràng và ngầm định . Khi nhà phát triển thể hiện ý định chuyển đổi giữa các loại bằng cách viết mã thích hợp, chẳng hạn như Number(value) , nó được gọi là ép kiểu rõ ràng (hoặc truyền kiểu).