Let's look at a example below.
// make constructor function
let Person = function (name) {
this.name = name;
};
// create foo object from Person
let foo = new Person("foo");
console.log(foo.name);
When Person()
is called as a constructor function, before executing function code, Person()
makes a empty object and bind it to this
. The most important thing is that the Person.prototype
is linked to this empty object as [[prototype]]
.
let foo = {
name: "foo",
age: "35",
gender: "man",
};
console.dir(foo);
// Object {name: "foo", age: "35", gender: "man", __proto__: Object.prototype}
let Person = function (name, age, gender, position) {
this.name = name;
this.age = age;
this.gender = gender;
};
let bar = new Person("seunghwan", 27, "male");
console.dir(bar);
// Person {name: "seunghwan", age: 27, gender: "male", __proto__: Person.prototype}
let baz = new Person("junyoung", 30, "female");
console.dir(baz);
// Person {name: "junyoung", age: 30, gender: "female", __proto__: Person.prototype}
Prototype of each object is different. It is Object.prototype
when using object literal. But it is Person.prototype
when using constructor function.
let Person = function (arg) {
// a way of correcting mistake
if (!(this instanceof Person)) {
return new Person(arg);
}
this.value = arg ? arg : 0;
};
let tmp = new Person(10);
console.log(tmp.value); // 10
let hello = Person(4);
console.log(hello.value); // 4
If Person()
is called as just function, global object(window
) is binded to this
. So !(this instanceof Person)
equals to true
and it will return new Person(arg)
. Therefore, even though we do mistake like not calling constructor function but just function, it corrects mistake by returning constructor function and executing it. That's why hello.value
return 4
.