JavaScript cho phép chúng ta làm việc với các nguyên hàm (chuỗi, số, v.v.) như thể chúng là các đối tượng. Họ cũng cung cấp các phương thức để gọi như vậy. Chúng ta sẽ nghiên cứu chúng sớm, nhưng trước tiên chúng ta sẽ xem cách nó hoạt động bởi vì, tất nhiên, Kiểu nguyên thủy không phải là đối tượng (và ở đây chúng ta sẽ làm cho nó rõ ràng hơn nữa).

Chúng ta hãy xem xét sự khác biệt chính giữa kiểu nguyên thủy và đối tượng.

Kiểu Nguyên thủy(primitive)

  • Là một giá trị của một kiểu nguyên thủy.
  • Có 7 kiểu nguyên thủy: string, number, bigint, boolean, symbol, nullundefined.

Một đối tượng(Object)

  • Có khả năng lưu trữ nhiều giá trị như các thuộc tính.
  • Có thể được tạo với {}, ví dụ : {name: "David", age: 30}. Có các kiểu đối tượng khác trong JavaScript: ví dụ, các hàm là các đối tượng.

Một trong những điều tốt nhất về các đối tượng là chúng ta có thể lưu trữ một hàm như một trong các thuộc tính của nó.

/*
Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
@author cafedevn
Contact: cafedevn@gmail.com
Fanpage: https://www.facebook.com/cafedevn
Instagram: https://instagram.com/cafedevn
Twitter: https://twitter.com/CafedeVn
Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
*/

let john = {
  name: "John",
  sayHi: function() {
    alert("Hi buddy!");
  }
};

john.sayHi(); // Hi buddy!

Vì vậy, ở đây chúng ta đã tạo ra một đối tượng johnvới phương thức sayHi.

Nhiều đối tượng được tích hợp sẵn trong Js, chẳng hạn như các đối tượng hoạt động với Date, Error, HTML, v.v. Chúng có các thuộc tính và phương thức khác nhau.

Nhưng, các tính năng này đi kèm với một chi phí!

Đối tượng là những thứ nặng nề hơn so với kiểu nguyên thủy(tốn tài nguyên nhiều).

1. Kiểu Nguyên thủy như một đối tượng

Đây là nghịch lý mà người tạo ra JavaScript phải đối mặt:

  • Có rất nhiều điều người ta muốn làm với một kiểu nguyên thủy như một chuỗi hoặc một số.
  • Kiểu nguyên thủy phải nhanh và nhẹ nhất có thể.

Giải pháp có vẻ hơi khó xử, nhưng đây là:

  1. Kiểu nguyên thủy vẫn là kiểu nguyên thủy. Một giá trị duy nhất như mong muốn.
  2. Ngôn ngữ cho phép truy cập vào các phương thức và thuộc tính của chuỗi, số, booleans và ký hiệu.
  3. Để làm việc đó, một trình bao bọc đối tượng đặc biệt, cung cấp hàm bổ sung được tạo ra và sau đó bị hủy.

Các “đối tượng wrappers” thì sẽ khác nhau đối với từng kiểu nguyên thủy và được gọi là: String, Number, BooleanSymbol. Vì vậy, họ cung cấp các bộ phương thức khác nhau.

Chẳng hạn, tồn tại một phương thức str.toUpperCase() trả về chữ viết hoa củastr.

Đây là cách nó hoạt động:

let str = "Hello";

alert( str.toUpperCase() ); // HELLO

Đơn giản phải không? Đây là những gì thực sự xảy ra trong str.toUpperCase():

  1. Chuỗi strlà một kiểu nguyên thủy. Vì vậy, trong thời điểm truy cập thuộc tính của nó, một đối tượng đặc biệt được tạo ra biết giá trị của chuỗi và có các phương thức hữu ích, như toUpperCase().
  2. Phương thức đó chạy và trả về một chuỗi mới (hiển thị bởi alert).
  3. Các vật thể đặc biệt bị phá hủy, để lại một str kiểu nguyên thủy .

Vì vậy, Kiểu nguyên thủy có thể cung cấp các phương thức, nhưng chúng vẫn nhẹ.

Công cụ JavaScript tối ưu hóa cao quá trình này. Nó thậm chí có thể bỏ qua việc tạo ra các đối tượng mở rộng khác. Nhưng nó vẫn phải tuân thủ các đặc điểm kỹ thuật và hành xử để tạo ra một biến.

Một số có các phương thức của riêng nó, ví dụ, hàm toFixed(n) làm tròn số với độ chính xác đã cho:

let n = 1.23456;

alert( n.toFixed(2) ); // 1.23

Chúng ta sẽ thấy các phương thức cụ thể hơn trong chương Số và Chuỗi .

Hàm constructor String/Number/Booleanchỉ được sử dụng nội bộ của các kiểu này thôi

Một số ngôn ngữ như Java cho phép chúng ta tạo ra các đối tượng để bao bọc rõ ràng cho các kiểu nguyên thủy bằng cách sử dụng cú pháp như new Number(1)hoặc new Boolean(false).

Trong JavaScript, mà cũng có thể làm vậy vì những lý do lịch sử, nhưng khuyến cáo không nên dùng nó. Bởi vì nó sẽ gây ra sự hiểu nhầm ở một số nơi.

Ví dụ:

alert( typeof 0 ); // "number"

alert( typeof new Number(0) ); // "object"!

Các đối tượng luôn luôn đúng trong if, vì vậy ở đây alert sẽ hiển thị:

/*
Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
@author cafedevn
Contact: cafedevn@gmail.com
Fanpage: https://www.facebook.com/cafedevn
Group: https://www.facebook.com/groups/cafedev.vn/
Instagram: https://instagram.com/cafedevn
Twitter: https://twitter.com/CafedeVn
Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
Pinterest: https://www.pinterest.com/cafedevvn/
YouTube: https://www.youtube.com/channel/UCE7zpY_SlHGEgo67pHxqIoA/
*/

let zero = new Number(0);

if (zero) { // zero is true, because it's an object
  alert( "zero is truthy!?!" );
}

Mặt khác, sử dụng các hàm tương tự String/Number/Booleanmà không có newlà một điều hoàn toàn lành mạnh và hữu ích. Họ chuyển đổi một giá trị thành loại tương ứng: thành một chuỗi, một số hoặc boolean (nguyên thủy).

Ví dụ: điều này hoàn toàn hợp lệ:

let num = Number("123"); // convert a string to number

null / undefined không có phương thức

Các kiểu nguyên thủy đặc biệt nullundefinedlà ngoại lệ. Chúng không có các đối tượng trình bao bọc tương ứng khác, và không cung cấp phương thức nào. Theo một nghĩa nào đó, nó là kiểu nguyên thủy nhất.

Cố gắng truy cập vào một thuộc tính có giá trị như vậy sẽ gây ra lỗi:

alert(null.test); // error

2. Tóm lược

  • Kiểu nguyên thủy ngoại trừ nullundefinedcung cấp nhiều phương pháp hữu ích. Chúng tôi sẽ nghiên cứu những người trong các chương sắp tới.
  • Các phương thức này hoạt động thông qua các đối tượng tạm thời, nhưng các công cụ JavaScript được điều chỉnh tốt để tối ưu hóa trong nội bộ, vì vậy chúng không tốn kém để gọi.

Full series tự học Javascript từ cơ bản tới nâng cao tại đây nha.

Nếu bạn thấy hay và hữu ích, bạn có thể tham gia các kênh sau của cafedev để nhận được nhiều hơn nữa:

Chào thân ái và quyết thắng!

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!