Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> JavaScript

Tạo Constructor Function với từ khóa new trong JavaScript

Constructor Function là hàm thông thường được gọi với từ khóa new để tạo instance. Theo convention: tên hàm viết **PascalCase**.

Quy trình khi gọi new Constructor():

  1. Tạo object rỗng {} gán cho this
  2. Link this.__proto__ = Constructor.prototype
  3. Thực thi body hàm (gán property vào this)
  4. Tự động trả về this (trừ khi return object khác)

Ví dụ minh họa

<!DOCTYPE html>
<html lang="vi">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Constructor với new</title>
  <style>
    body { font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; padding: 20px; }
    .result { font-size: 18px; font-weight: 500; margin: 10px 0; color: green; }
    button { padding: 8px 16px; cursor: pointer; }
  </style>
</head>
<body>
  <h1>JavaScript Constructor với từ khóa new</h1>
  <div class="result" id="result"></div>
  <button class="Btn" id="btn">NHẤN VÀO ĐÂY</button>
  <h3> Nhấn nút để tạo instance từ Constructor </h3>
  <script>
    const resEle = document.querySelector("#result");
    
    // Constructor Function (PascalCase)
    function Human(firstName, lastName, age) {
      this.firstName = firstName;
      this.lastName = lastName;
      this.age = age;
      // Không cần return this (tự động)
    }
    
    // Tạo instance
    const obj = new Human('Rohan', 'Sharma', 22);
    
    document.querySelector("#btn").addEventListener("click", () => {
      for (const key in obj) {
        resEle.innerHTML += `Key = ${key} : Value = ${obj[key]}
`; } resEle.innerHTML += `
obj instanceof Human: ${obj instanceof Human}`; // true resEle.innerHTML += `
obj.constructor === Human: ${obj.constructor === Human}`; // true resEle.innerHTML += `
Object.getPrototypeOf(obj) === Human.prototype: ${Object.getPrototypeOf(obj) === Human.prototype}`; }); </script> </body> </html>

Kết quả

Key = firstName : Value = Rohan
Key = lastName : Value = Sharma
Key = age : Value = 22

obj instanceof Human: true
obj.constructor === Human: true
Object.getPrototypeOf(obj) === Human.prototype: true

Quên new sẽ sao?

function Human(name) { this.name = name; }

const a = new Human("Alice"); // OK: this = instance mới
const b = Human("Bob");       // ❌ this = window (non-strict) hoặc undefined (strict)
// b = undefined, window.name = "Bob" (leak global!)

Bảo vệ khỏi quên new (New.target - ES2015):

function Human(name) {
  if (!new.target) {
    // Được gọi không có new
    return new Human(name); // Tự động new
    // Hoặc throw new Error("Phải dùng new");
  }
  this.name = name;
}

const a = new Human("Alice"); // OK
const b = Human("Bob");       // OK - tự động new

Prototype Methods (Shared methods):

function Human(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
}

// Thêm method vào prototype (chia sẻ cho tất cả instances)
Human.prototype.getFullName = function() {
  return `${this.firstName} ${this.lastName}`;
};

Human.prototype.greet = function() {
  return `Xin chào, tôi là ${this.getFullName()}`;
};

const user = new Human("Rohan", "Sharma");
user.getFullName(); // "Rohan Sharma"
user.greet();       // "Xin chào, tôi là Rohan Sharma"

Class Syntax (ES6 - Syntactic Sugar):

class Human {
  constructor(firstName, lastName, age) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.age = age;
  }
  
  getFullName() {
    return `${this.firstName} ${this.lastName}`;
  }
  
  static species = "Homo sapiens"; // Static property
  
  static createBaby(name) { // Static method
    return new Human(name, "Unknown", 0);
  }
}

const user = new Human("Rohan", "Sharma", 22);
// Tương đương constructor function nhưng syntax sạch hơn

So sánh Constructor Function vs Class:

Đặc điểmConstructor FunctionClass (ES6)
SyntaxFunction + prototypeClass keyword
HoistingHoisted (function declaration)Không hoisted (TDZ)
Strict modeTự chọnLuôn strict mode
MethodsGán vào prototype thủ côngTrong class body
StaticConstructor.prop = ...static prop = ...
ExtendsManual prototype chainextends, super()