Sự khác biệt giữa function Person() {}
, var person = Person()
, và var person = new Person()
là gì?
Trong JavaScript, có ba cách sử dụng thường gặp liên quan đến hàm và đối tượng: function declaration, function invocation, và constructor invocation. Chúng ta sẽ phân tích kỹ từng cách sử dụng này và sự khác biệt giữa chúng.
1. function Person() {}
(Function Declaration)
Đây là một function declaration (khai báo hàm) đơn giản. Hàm này có thể được sử dụng như một hàm thông thường, hoặc như một constructor khi kết hợp với từ khóa new
.
Ví dụ:
function Person() {
console.log('This is a function declaration');
}
- Chức năng:
Person
là một hàm, và bạn có thể gọi nó ở bất cứ đâu trong phạm vi của nó. Trong trường hợp này, Person
có thể được sử dụng để thực thi một đoạn mã cụ thể khi gọi hàm.
- Hoisting: Hàm này được hoisted (kéo lên đầu phạm vi), vì vậy bạn có thể sử dụng
Person
trước cả khi nó được khai báo trong mã của bạn.
2. var person = Person()
(Function Invocation)
Ở đây, bạn đang gọi hàm Person
như một function invocation (gọi hàm thông thường) mà không sử dụng từ khóa new
.
Ví dụ:
function Person() {
console.log('This is a function invocation');
return { name: 'John' };
}
var person = Person();
console.log(person); // { name: 'John' }
- Chức năng: Khi bạn gọi
Person()
mà không có từ khóa new
, hàm sẽ thực thi giống như bất kỳ hàm nào khác. Nó có thể trả về một giá trị cụ thể (trong ví dụ trên, nó trả về một đối tượng { name: 'John' }
).
- Không có đối tượng mới được tạo ra: Khi bạn gọi hàm này, không có đối tượng mới nào được tạo ra, và từ khóa
this
trong hàm sẽ tham chiếu đến phạm vi toàn cục hoặc đối tượng hiện tại.
- Kết quả: Biến
person
sẽ chứa giá trị trả về từ hàm Person()
. Nếu hàm không có giá trị trả về (trả về undefined
), person
sẽ là undefined
.
3. var person = new Person()
(Constructor Invocation)
Khi bạn sử dụng từ khóa new
, hàm Person
được coi là một constructor function (hàm khởi tạo) và sẽ tạo ra một đối tượng mới.
Ví dụ:
function Person() {
this.name = 'John';
console.log('This is a constructor invocation');
}
var person = new Person();
console.log(person.name); // 'John'
- Chức năng: Khi bạn gọi hàm
Person()
với từ khóa new
, một đối tượng mới được tạo ra và this
bên trong hàm sẽ tham chiếu đến đối tượng đó. Hàm sẽ gán các thuộc tính cho đối tượng mới này.
- Constructor Invocation: Sử dụng từ khóa
new
sẽ thực hiện ba điều chính:
- Tạo một đối tượng trống mới.
- Gán đối tượng mới này cho từ khóa
this
trong hàm.
- Nếu hàm không trả về một đối tượng cụ thể, nó sẽ ngầm trả về đối tượng mới được tạo ra.
- Kết quả: Biến
person
sẽ chứa đối tượng mới được tạo bởi hàm Person
, với thuộc tính name
là 'John'
.
Sự khác biệt chính
function Person() {}
(Function Declaration):
- Đây là cách khai báo một hàm thông thường. Hàm này có thể được sử dụng để gọi như một hàm thông thường hoặc như một hàm khởi tạo (constructor).
var person = Person()
(Function Invocation):
- Đây là cách gọi hàm
Person
như một hàm thông thường. Không có đối tượng mới nào được tạo ra và từ khóa this
sẽ tham chiếu đến phạm vi toàn cục hoặc đối tượng hiện tại.
- Nếu hàm
Person
trả về một giá trị, biến person
sẽ lưu giá trị đó.
var person = new Person()
(Constructor Invocation):
- Khi sử dụng từ khóa
new
, một đối tượng mới được tạo ra. Hàm Person
trở thành một constructor và gán các thuộc tính cho đối tượng mới.
- Biến
person
sẽ lưu đối tượng mới được tạo ra bởi hàm Person
.
Ví dụ minh họa chi tiết
// Khai báo hàm
function Person() {
this.name = 'John';
console.log('Person function is called');
return { age: 30 };
}
// Function Invocation
var person1 = Person(); // Gọi hàm như một hàm thông thường
console.log(person1); // { age: 30 }
// Constructor Invocation
var person2 = new Person(); // Gọi hàm như một constructor
console.log(person2); // { age: 30 }
console.log(person2.name); // undefined (vì đối tượng trả về từ hàm không chứa thuộc tính name)
Trong ví dụ này:
person1
chứa đối tượng { age: 30 }
do hàm Person
trả về khi gọi hàm thông thường.
person2
cũng chứa đối tượng { age: 30 }
, nhưng nó không chứa thuộc tính name
vì hàm đã trả về đối tượng thay vì this
.