Trong hướng dẫn này, mình sẽ giúp bạn tìm hiểu về Constructor trong JavaScript và cách sử dụng từ khóa new để tạo một đối tượng. (Và cả cách không sử dụng từ khóa new)
1. Giới thiệu về hàm Constructor trong JavaScript
Trong hướng dẫn về các Object trong JavaScript, bạn đã học cách sử dụng cú pháp (theo nghĩa đen) của đối tượng để tạo một đối tượng mới:
// Tạo một đối tượng
let student = {
name: 'Ngọc Anh',
age: 18
}
Trong thực tế, bạn thường cần tạo nhiều đối tượng giống nhau như một danh sách sinh viên.
Để làm điều này, bạn có thể sử dụng một hàm constructor (hàm khởi tạo) để xác định một kiểu tùy chỉnh và toán tử mới để tạo nhiều đối tượng từ kiểu này.
Về mặt kỹ thuật, một hàm constructor trong JavaScript là một hàm thông thường với quy ước sau:
-
Tên của một hàm khởi tạo bắt đầu bằng một chữ cái viết HOA như Student, Document, v.v.
-
Một hàm khởi tạo chỉ nên được gọi với toán tử
new
.
> Lưu ý: Phiển bản ES6 của JavaScript giới thiệu từ khóa class cho phép bạn định nghĩa một kiểu tùy chỉnh. Tuy nhiên, class cũng chỉ là cú pháp trên các hàm khởi tạo với một số cải tiến.
Ví dụ sau định nghĩa một hàm khởi tạo được gọi là Student
:
// Hàm constructor
function Student(name, age) {
this.name = name;
this.age = age;
}
Như bạn có thể thấy, Student
giống như một hàm thông thường ngoại trừ tên của nó bắt đầu bằng chữ S
viết hoa.
Để tạo một phiên bản mới của Student
, bạn sử dụng toán tử new
:
let student = new Student('Ngọc Anh', 18);
Về cơ bản, nhà điều hành mới thực hiện những việc sau:
-
Tạo một đối tượng trống mới và gán nó cho
this
.
-
Gán các đối số
'Ngọc Anh'
và 18
cho các thuộc tính name
và age
Nó tương đương về mặt chức năng như sau:
// Hàm constructor
function Student(name, age) {
// this = {};
// Thêm thuộc tính cho this
this.name = name;
this.age = age;
// return this;
}
Và câu lệnh này:
// Tạo một đối tượng mới từ Student
// và gán giá trị khởi tạo cho nó
let student = new Student('Ngọc Anh', 18);
Thì tương đương với:
let student = {
name: 'Ngọc Anh',
age: 18
}
Tuy nhiên, hàm hàm constructor Student
này cho phép bạn tạo nhiều đối tượng giống nhau. Ví dụ:
// Tạo mới đối tượng 1
let student1 = new Student('Ngọc Anh', 18);
// Tạo mới đối tượng 2
let student2 = new Student('Vũ Hà', 20);
> Tham khảo: Constructor trong Java
2. Thêm phương thức vào hàm constructor trong JavaScript
Một đối tượng có thể có các phương thức thao tác với dữ liệu của nó. Để thêm một phương thức vào một đối tượng được tạo thông qua constructor, bạn có thể sử dụng từ khóa this
. Ví dụ:
// Hàm constructor
function Student(name, age) {
// Thêm thuộc tính cho this
this.name = name;
this.age = age;
// Thêm phương thức
this.getInfor = function () {
return this.name + " " + this.age + " tuổi";
};
}
Bây giờ, bạn có thể tạo một đối tượng mới từ Student
và gọi phương thức getInfor()
:
let student = new Student('Ngọc Anh', 18);
console.log(student.getInfor());
Kết quả:
Ngọc Anh 18 tuổi
Vấn đề ở đây là khi bạn tạo nhiều đối tượng từ Student
, this.getInfor()
sẽ bị lặp lại nhiều lần.
Do đó, đây không phải là cách quản lý bộ nhớ hiệu quả.
Để giải quyết vấn đề này, bạn có thể sử dụng Prototype để tất cả các đối tượng của một kiểu tùy chỉnh có thể chia sẻ cùng một phương thức.
return
từ hàm Constructor
Thông thường, một hàm constructor được return
ngầm định giá trị this
được thiết lập cho đối tượng mới được tạo.
Nhưng nếu nó có câu lệnh trả về, thì đây là quy tắc của nó:
-
Nếu
return
được gọi với một đối tượng, hàm constructor
sẽ trả về đối tượng đó thay vì đối tượng this
.
-
Nếu
return
được gọi với một giá trị khác với một đối tượng, nó sẽ bị bỏ qua.
3. Gọi constructor mà không có từ khóa new
Có thể gọi một hàm tạo mà không có từ khóa new
như sau:
let student = Student('Ngọc Anh', 18);
Trong trường hợp này, Student
chỉ thực thi giống như một hàm thông thường. Do đó, hàm this
bên trong hàm Student
không liên kết với biến student
mà là đối tượng toàn cục.
Nếu bạn cố gắng truy cập thuộc tính name
hoặc age
, bạn sẽ gặp lỗi:
console.log(student.name);
Kết quả:
error: Cannot read property 'name' of undefined
Tương tự, bạn không thể truy cập phương thức getInfor()
vì nó bị ràng buộc với đối tượng toàn cục.
student.getInfor();
Lỗi:
error: Cannot read property 'getInfor' of undefined
Vì thế, để ngăn một hàm constructor được gọi mà không có từ khóa new
, ES6 đã giới thiệu thuộc tính new.target
.
Nếu một hàm constructor được gọi với từ khóa new
, new.target
trả về một tham chiếu đến hàm. Nếu không, nó trả về undefined
.
Hãy hiển thị giá trị của new.target
cho console bên trong hàm Student
:
// Hàm constructor
function Student(name, age) {
console.log(new.target);
// Thêm thuộc tính cho this
this.name = name;
this.age = age;
// Thêm phương thức
this.getInfor = function () {
return this.name + " " + this.age + " tuổi";
};
}
Bây giờ, chúng ta lại thử tạo một đối tượng mới từ Student
nhưng không sử dụng từ khóa new
.
let student = Student('Ngọc Anh', 18);
Kết quả nhận được trong console:
undefined
Tuy nhiên, nếu sử dụng new
thì nó trả về một tham chiếu đến hàm Student
:
let student = new Student('Ngọc Anh', 18);
Trong console:
function Student....
Và bằng cách tận dụng new.target
, bạn có thể buộc người dùng sử dụng constructor phải gọi nó bằng từ khóa new
.
Nếu không, hãy ném ra một lỗi:
// Hàm constructor
function Student(name, age) {
if (!new.target) {
throw Error("Không thể gọi mà thiếu 'new'");
}
// Thêm thuộc tính cho this
this.name = name;
this.age = age;
// Thêm phương thức
this.getInfor = function () {
return this.name + " " + this.age + " tuổi";
};
}
Ngoài ra, bạn có thể làm cho cú pháp linh hoạt hơn bằng cách tự tạo một đối tượng Student
mới nếu người dùng không sử dụng từ khóa new
:
// Hàm constructor
function Student(name, age) {
if (!new.target) {
return new Student(name, age);
}
// Thêm thuộc tính cho this
this.name = name;
this.age = age;
// Thêm phương thức
this.getInfor = function () {
return this.name + " " + this.age + " tuổi";
};
}
// Tạo đối tượng mà không có từ khóa new
let student = Student('Ngọc Anh', 18);
// Lấy thông tin
console.log(student.getInfor());
Kết quả:
Ngọc Anh 18 tuổi
Cách này thường được sử dụng trong các thư viện hoặc framework bạn sẽ thường gặp nếu như học React / Angular / Vue bởi vì nó làm cho cú pháp linh hoạt hơn.
Tổng kết
Như vậy là trong bài viết này mình đã giúp bạn tìm hiểu về hàm Constructor trong JavaScript và biết cách sử dụng nó để tạo ra nhiều đối tượng khác nhau.
Hi vọng giúp được bạn trong quá trình học JavaScript của bạn.
> Nếu bạn yêu thích JS và muốn đi chuyên sâu về nó thì đừng quên tham gia KHÓA HỌC FRONT END (với React.js) tại NIIT - ICT Hà Nội nhé. Học với dự án + Cam kết hỗ trợ giới thiệu việc làm / địa chỉ thực tập.
---
HỌC VIỆN ĐÀO TẠO CNTT NIIT - ICT HÀ NỘI
Học Lập trình chất lượng cao (Since 2002). Học thực tế + Tuyển dụng ngay!
Đc: Tầng 3, 25T2, N05, Nguyễn Thị Thập, Cầu Giấy, Hà Nội
SĐT: 02435574074 - 0383.180086
Email: hello@niithanoi.edu.vn
Fanpage: https://facebook.com/NIIT.ICT/
#niit #icthanoi #niithanoi #niiticthanoi #hoclaptrinh #khoahoclaptrinh #hoclaptrinhjava #hoclaptrinhphp #java #php #python