Bất kì 1 ngôn ngữ nào cũng có cấu trúc dữ liệu của nó. Javascript là ngôn ngữ động, khi bạn tạo ra 1 biến JavaScript không ràng buộc kiểu dữ liệu của biến.

Qua quá trình sử dụng kiểu dữ liệu của biến có thể bị thay đổi dẫn đến việc khó kiểm soát và dễ sinh bugs. Ngày nay có nhiều JavaScript compiler có hỗ trợ static type checker như Typescript, Babel ,Flowjs, etc....

Nhưng nếu không xài những anh chàng này thì sẽ có 1 trick để bạn lấy chính xác kiểu dữ liệu của 1 biến trong JavaScript.

const whatType = obj => {
  return {}.toString
    .call(obj)
    .match(/\s([a-zA-Z]+)/)[1]
    .toLowerCase();
};

whatType(1) // number
whatType('1') // string 
whatType(null) // null
whatType([])// array
whatType(()=>{})// function
whatType() // undefined
whatType(true) // boolean
whatType(Symbol(1)) // symbol
whatType({}) // object

Giải thích:

Trong JavaScript mỗi Object tạo ra đều có hàm toString trả về miêu tả của 1 object.

The toString() method returns a string representing the object.(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString)

Vậy đầu tiên mình gọi Object.toString để lấy ra function toString của Object. Viết tường minh ra sẽ như vầy.

const toString={}.toString 
// các bạn để ý mình chưa thực thi hàm toString() nha 
// sau đó mình sẽ thực thi hàm toString này thông qua 
// method call.

const representing = toString.call(1)
console.log(representing) // "[object Number]"

Function.property.call nhận tham số đầu tiên làm giá trị this của Function nên giá trị mình tryền vào ở hàm call chính là giá trị this của function toString. Như ở trên hàm toString khi thực thi sẽ return về miêu tả của 1 object đó nên kết quả mình nhận được khi truyền tham số 1 vào là "[object Number]".

Việc còn lại là format chuỗi này ta sẽ lấy được giá kiểu dữ liệu của biến.

const representing = toString.call(1)
representing.match(/\s([a-zA-Z]+)/)[1].toLowerCase();
=> number

Viết ngắn gọn lại là:

const whatType = obj =>
         {}.toString
         .call(obj)
         .match(/\s([a-zA-Z]+)/)[1]
         .toLowerCase();