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à18cho các thuộc tínhnamevà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àmconstructorsẽ trả về đối tượng đó thay vì đối tượngthis.
	- 
		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