quiz/js: difference between function declaration, function call, and constructor call (#442)

This commit is contained in:
Nitesh Seram 2024-06-04 14:37:43 +05:30 committed by GitHub
parent f2b326c982
commit 87674b2103
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 57 additions and 5 deletions

View File

@ -2,11 +2,35 @@
title: 'Difference between: `function Person(){}`, `var person = Person()`, and `var person = new Person()`?'
---
This question is pretty vague. Our best guess at its intention is that it is asking about constructors in JavaScript. Technically speaking, `function Person(){}` is just a normal function declaration. The convention is to use PascalCase for functions that are intended to be used as constructors.
## TL;DR
`var person = Person()` invokes the `Person` as a function, and not as a constructor. Invoking as such is a common mistake if the function is intended to be used as a constructor. Typically, the constructor does not return anything, hence invoking the constructor like a normal function will return `undefined` and that gets assigned to the variable intended as the instance.
- `function Person(){}`: A function declaration in JavaScript. It can be used as a regular function or as a constructor.
- `var person = Person()`: Calls `Person` as a regular function, not a constructor. If Person is intended to be a constructor, this will lead to unexpected behavior.
- `var person = new Person()`: Creates a new instance of `Person`, correctly utilizing the constructor function to initialize the new object.
`var person = new Person()` creates an instance of the `Person` object using the `new` operator, which inherits from `Person.prototype`. An alternative would be to use `Object.create`, such as: `Object.create(Person.prototype)`.
| Aspect | `function Person(){}` | `var person = Person()` | `var person = new Person()` |
|------------------|-----------------------|---------------------------------------------|-----------------------------------|
| Type | Function declaration | Function call | Constructor call |
| Usage | Defines a function | Invokes `Person` as a regular function | Creates a new instance of `Person`|
| Instance Creation| No instance created | No instance created | New instance created |
| Common Mistake | N/A | Misusing as constructor leading to undefined| None (when used correctly) |
---
## Function declaration
`function Person(){}` is a standard function declaration in JavaScript. When written in PascalCase, it follows the convention for functions intended to be used as constructors.
```js
function Person(name) {
this.name = name;
}
```
This code defines a function named `Person` that takes a parameter `name` and assigns it to the `name` property of the object created from this constructor function. When the `this` keyword is used in a constructor, it refers to the newly created object.
## Function call
`var person = Person()` simply invoke the function's code. When you invoke `Person` as a regular function (i.e., without the `new` keyword), the function does not behave as a constructor. Instead, it executes its code and returns `undefined` if no return value is specified and that gets assigned to the variable intended as the instance. Invoking as such is a common mistake if the function is intended to be used as a constructor.
```js
function Person(name) {
@ -16,8 +40,36 @@ function Person(name) {
var person = Person('John');
console.log(person); // undefined
console.log(person.name); // Uncaught TypeError: Cannot read property 'name' of undefined
```
In this case, `Person('John')` does not create a new object. The `person` variable is assigned `undefined` because the `Person` function does not explicitly return a value. Attempting to access `person.name` throws an error because `person` is `undefined`.
## Constructor call
`var person = new Person()` creates an instance of the `Person` object using the new operator, which inherits from `Person.prototype`. An alternative would be to use `Object.create`, such as: `Object.create(Person.prototype)` and `Person.call(person, 'John')` initializes the object.
```js
function Person(name) {
this.name = name;
}
var person = new Person('John');
console.log(person); // Person { name: "John" }
console.log(person.name); // "john"
console.log(person); // Person { name: 'John' }
console.log(person.name); // 'John'
// Alternative
var person1 = Object.create(Person.prototype);
Person.call(person1, 'John');
console.log(person1); // Person { name: 'John' }
console.log(person1.name); // 'John'
```
In this case, `new Person('John')` creates a new object, and `this` within `Person` refers to this new object. The `name` property is correctly set on the new object. The `person` variable is assigned the new instance of `Person` with the name property set to `'John'`. And for the alternative object creation, `Object.create(Person.prototype)` creates a new object with `Person.prototype` as its prototype. `Person.call(person, 'John')` initializes the object, setting the `name` property.
## Follow-Up Questions
- What are the differences between function constructors and ES6 class syntax?
- What are some common use cases for Object.create?
## Further reading
- [MDN Web Docs: Object prototypes](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_prototypes)
- [Differences between Class and Function Constructors](https://www.greatfrontend.com/questions/quiz/what-are-the-differences-between-es6-class-and-es5-function-constructors)
- [How `this` keyword works in JavaScript?](https://www.greatfrontend.com/questions/quiz/explain-how-this-works-in-javascript)