Kiểu dữ liệu và kiểm tra kiểu là các khía cạnh cơ bản của bất kỳ ngôn ngữ lập trình nào.
Nhiều ngôn ngữ lập trình như Java có kiểm tra kiểu nghiêm ngặt. Điều này có nghĩa là nếu một biến được định nghĩa với một kiểu cụ thể thì nó chỉ có thể chứa giá trị của kiểu đó.
Tuy nhiên, JavaScript là một ngôn ngữ được gõ lỏng lẻo (hoặc được gõ động). Điều này có nghĩa là một biến có thể chứa một giá trị thuộc bất kỳ kiểu nào. Mã JavaScript có thể thực thi như thế này:
let one = 1;
one="one";
one = true;
one = Boolean(true);
one = String('It is possible');
Với suy nghĩ này, điều quan trọng là phải biết loại biến tại bất kỳ thời điểm nào.
Loại của một biến được xác định bởi loại giá trị được gán cho nó. JavaScript có một toán tử đặc biệt gọi là typeof
cho phép bạn nhận được loại giá trị bất kỳ.
Trong bài viết này, chúng ta sẽ tìm hiểu cách typeof
được sử dụng, cùng với một số vấn đề cần chú ý.
Hãy xem nhanh các kiểu dữ liệu JavaScript trước khi chúng ta đi sâu vào typeof
nhà điều hành.
Trong JavaScript, có bảy loại nguyên thủy. Một nguyên thủy là bất cứ thứ gì không phải là một đối tượng. Họ đang:
- Chuỗi
- Con số
- BigInt
- Biểu tượng
- Boolean
- không xác định
- vô giá trị
Mọi thứ khác là một object
– thậm chí bao gồm cả array
và function
. Một đối tượng là một tập hợp các cặp khóa-giá trị.
Các typeof
toán tử chỉ nhận một toán hạng (toán tử một ngôi). Nó đánh giá loại toán hạng và trả về kết quả dưới dạng một chuỗi. Đây là cách bạn sử dụng nó khi đánh giá loại số, 007.
typeof 007; // returns 'number'
Có cú pháp thay thế cho typeof
nơi bạn có thể sử dụng nó như một function
:
typeof(operand)
Cú pháp này hữu ích khi bạn muốn đánh giá một biểu thức hơn là một giá trị đơn lẻ. Đây là một ví dụ về điều đó:
typeof(typeof 007); // returns 'string'
Trong ví dụ trên, biểu thức typeof 007
đánh giá loại số và trả về chuỗi ‘số’. typeof('number')
sau đó kết quả trong 'string'
.
Hãy xem một ví dụ khác để hiểu tầm quan trọng của dấu ngoặc đơn với typeof
nhà điều hành.
typeof(999-3223); // returns, "number"
Nếu bạn bỏ qua dấu ngoặc đơn, nó sẽ trả về, NaN
(Không phải là một con số):
typeof 999-3223; // returns, NaN
Điều này là bởi vì, đầu tiên typeof 999
sẽ dẫn đến một chuỗi, “số”. Cách diễn đạt "number" - 32223
dẫn đến NaN như xảy ra khi bạn thực hiện phép trừ giữa một chuỗi và số.
Kiểu JavaScript Ví dụ
Đoạn mã sau hiển thị kết quả kiểm tra loại của các giá trị khác nhau bằng cách sử dụng typeof
nhà điều hành.
typeof 0; //'number'
typeof +0; //'number'
typeof -0; //'number'
typeof Math.sqrt(2); //'number'
typeof Infinity; //'number'
typeof NaN; //'number', even if it is Not a Number
typeof Number('100'); //'number', After successfully coerced to number
typeof Number('freeCodeCamp'); //'number', despite it can not be coerced to a number
typeof true; //'boolean'
typeof false; //'boolean'
typeof Boolean(0); //'boolean'
typeof 12n; //'bigint'
typeof ''; //'string'
typeof 'freeCodeCamp'; //'string'
typeof `freeCodeCamp is awesome`; //'string'
typeof '100'; //'string'
typeof String(100); //'string'
typeof Symbol(); //'symbol'
typeof Symbol('freeCodeCamp'); //'symbol'
typeof {blog: 'freeCodeCamp', author: 'Tapas A'}; //'object';
typeof ['This', 'is', 101]; //'object'
typeof new Date(); //'object'
typeof Array(4); //'object'
typeof new Boolean(true); //'object';
typeof new Number(101); //'object';
typeof new String('freeCodeCamp'); //'object';
typeof new Object; //'object'
typeof alert; //'function'
typeof function () {}; //'function'
typeof (() => {}); //'function' - an arrow function so, parenthesis is required
typeof Math.sqrt; //'function'
let a;
typeof a; //'undefined'
typeof b; //'undefined'
typeof undefined; //'undefined'
typeof null; //'object'
Bảng bên dưới hiển thị các giá trị kiểm tra loại của typeof
:
LOẠI | GIÁ TRỊ TRẢ LẠI CỦA TYPEOF |
---|---|
Chuỗi | 'string' |
Con số | 'number' |
BigInt | 'bigint' |
Biểu tượng | 'symbol' |
Boolean | 'boolean' |
không xác định | 'undefined' |
đối tượng chức năng | 'function' |
vô giá trị | 'object' (xem bên dưới!) |
Bất kỳ đối tượng nào khác | 'object' |
Có những trường hợp mà các typeof
toán tử có thể không trả về các loại bạn mong đợi. Điều này có thể gây nhầm lẫn và sai sót. Dưới đây là một vài trường hợp.
Loại NaN là một số
typeof NaN; //'number', even if it is Not a Number
Các typeof NaN
Là 'number'
. Điều này thật kỳ lạ, vì lẽ ra chúng ta không nên phát hiện ra một NaN
sử dụng typeof
. Có nhiều cách tốt hơn để đối phó với nó. Chúng ta sẽ thấy họ trong một phút.
loại null
là đối tượng
typeof null; //'object'
Trong JavaScript, typeof null
là một đối tượng mang lại ấn tượng sai lầm rằng, null
là một đối tượng trong đó nó là một giá trị nguyên thủy.
kết quả này của typeof null
thực sự là một lỗi trong ngôn ngữ. Trước đây đã có một nỗ lực để sửa nó nhưng nó đã bị từ chối do vấn đề tương thích ngược.
Loại biến không được khai báo là không xác định
Trước ES6, kiểm tra kiểu trên một biến không được khai báo được sử dụng để dẫn đến kết quả 'undefined'
. Nhưng đây không phải là một cách an toàn để xử lý lỗi.
Với ES6, chúng ta có thể khai báo các biến trong phạm vi khối bằng let
hoặc const
từ khóa. Nếu bạn sử dụng chúng với typeof
toán tử trước khi chúng được khởi tạo, chúng sẽ ném một ReferenceError
.
typeof cat; // ReferenceError
let cat="brownie";
Loại hàm tạo là một đối tượng
Tất cả các hàm tạo, ngoại trừ hàm Function
hàm tạo, sẽ luôn là typeof
‘vật’.
typeof new String('freeCodeCamp'); //'object'
Điều này có thể dẫn đến một số nhầm lẫn, vì chúng tôi mong đợi nó là loại thực tế (trong ví dụ trên, một string
loại).
Kiểu của một mảng là một đối tượng
Mặc dù đúng về mặt kỹ thuật, đây có thể là điều đáng thất vọng nhất. Chúng tôi muốn phân biệt giữa Mảng và Đối tượng ngay cả khi Mảng về mặt kỹ thuật là Đối tượng trong JavaScript.
typeof Array(4); //'object'
May mắn thay, có nhiều cách để phát hiện Mảng một cách chính xác. Chúng ta sẽ sớm thấy điều đó.
Bây giờ chúng ta đã thấy một số hạn chế với typeof
toán tử, hãy xem cách khắc phục chúng và kiểm tra kiểu tốt hơn.
Cách phát hiện NaN
Trong JavaScript, NaN là một giá trị đặc biệt. Giá trị NaN biểu thị kết quả của một biểu thức số học không thể biểu diễn trên thực tế. Ví dụ,
let result = 0/0;
console.log(result); // returns, NaN
Ngoài ra, nếu chúng ta thực hiện bất kỳ phép toán số học nào với NaN
nó sẽ luôn dẫn đến một NaN
.
console.log(NaN + 3); // returns, NaN
Loại kiểm tra trên NaN bằng cách sử dụng typeof
toán tử không giúp được gì nhiều vì nó trả về kiểu dưới dạng 'number'
. JavaScript có một chức năng toàn cầu được gọi là isNaN()
để phát hiện xem kết quả có phải là NaN hay không.
isNaN(0/0); // returns, true
Nhưng cũng có một vấn đề ở đây.
isNaN(undefined); // returns true for 'undefined'
Trong ES6, phương thức isNaN()
được thêm vào toàn cầu Number
vật. Phương pháp này đáng tin cậy hơn nhiều và vì vậy nó là phương pháp được ưa thích hơn.
Number.isNaN(0/0); // returns, true
Number.isNaN(undefined); // returns, false
Một khía cạnh thú vị khác của NaN
là nó là giá trị JavaScript duy nhất không bao giờ bằng bất kỳ giá trị nào khác, kể cả chính nó. Vì vậy, đây là một cách khác để phát hiện NaN cho các môi trường không hỗ trợ ES6:
function isNaN (input) {
return input !== input;
}
Cách phát hiện null trong JavaScript
Chúng tôi đã thấy, phát hiện null bằng cách sử dụng typeof
nhà điều hành là khó hiểu. Cách ưa thích để kiểm tra xem thứ gì đó có rỗng hay không là sử dụng toán tử đẳng thức nghiêm ngặt (===
).
function isNull(input) {
return input === null;
}
Đảm bảo không sử dụng ==
do nhầm lẫn. Sử dụng ==
thay cho ===
sẽ dẫn đến phát hiện loại sai lệch.
Cách phát hiện một mảng trong JavaScript
Từ ES6 trở đi, chúng ta có thể phát hiện một mảng bằng cách sử dụng Array.isArray
phương pháp.
Array.isArray([]); // returns true
Array.isArray({}); // returns false
Trước ES6, chúng ta có thể sử dụng instanceof
toán tử để xác định một Mảng:
function isArray(input) {
return input instanceof Array;
}
Có một cách chúng ta có thể tạo một giải pháp chung để kiểm tra kiểu. Hãy xem phương pháp, Object.prototype.toString
. Điều này rất mạnh mẽ và cực kỳ hữu ích để viết một phương thức tiện ích để kiểm tra kiểu.
Khi nào Object.prototype.toString
được gọi bằng cách sử dụng call()
hoặc apply()
nó trả về loại đối tượng ở định dạng: [object Type]
. Các Type
một phần trong giá trị trả về là loại thực tế.
Hãy xem cách nó hoạt động với một số ví dụ:
// returns '[object Array]'
Object.prototype.toString.call([]);
// returns '[object Date]'
Object.prototype.toString.call(new Date());
// returns '[object String]'
Object.prototype.toString.call(new String('freeCodeCamp'));
// returns '[object Boolean]'
Object.prototype.toString.call(new Boolean(true));
// returns '[object Null]'
Object.prototype.toString.call(null);
Vì vậy, điều này có nghĩa là nếu chúng ta chỉ lấy chuỗi trả về và loại bỏ Type
một phần, chúng ta sẽ có kiểu thực tế. Đây là một nỗ lực để làm điều này:
function typeCheck(value) {
const return_value = Object.prototype.toString.call(value);
// we can also use regex to do this...
const type = return_value.substring(
return_value.indexOf(" ") + 1,
return_value.indexOf("]"));
return type.toLowerCase();
}
Bây giờ, chúng ta có thể sử dụng typeCheck
chức năng phát hiện các loại:
typeCheck([]); // 'array'
typeCheck(new Date()); // 'date'
typeCheck(new String('freeCodeCamp')); // 'string'
typeCheck(new Boolean(true)); // 'boolean'
typeCheck(null); // 'null'
Để tóm tắt những gì chúng ta đã học được trong bài viết này:
- Kiểm tra loại JavaScript không nghiêm ngặt như các ngôn ngữ lập trình khác.
- Sử dụng
typeof
toán tử để phát hiện các loại. - Có hai biến thể của
typeof
cú pháp toán tử:typeof
vàtypeof(expression)
. - kết quả của một
typeof
nhà điều hành đôi khi có thể gây hiểu nhầm. Chúng ta cần dựa vào các phương pháp có sẵn khác (Number.isNaN
,Array.isArry
v.v.) trong những trường hợp đó. - chúng ta có thể sử dụng
Object.prototype.toString
để tạo một phương pháp phát hiện loại chung.
Cảm ơn bạn đã đọc đến đây! Kết nối nào. Bạn có thể @ tôi trên Twitter (@tapasadhikary) với nhận xét.
Bạn cũng có thể thích những bài viết khác:
Đó là tất cả cho bây giờ. Hẹn gặp lại bạn với bài viết tiếp theo của tôi sớm. Cho đến lúc đó, xin hãy chăm sóc bản thân thật tốt.