Why is old constructor for function called? - javascript

It is my understanding that when you change the function prototype of a function to point to a different object the constructor of the new prototype will point to the new object's prototype constructor.
From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new:
When the code new Foo(...) is executed, the following things happen:
1) A new object is created, inheriting from Foo.prototype.
2) The constructor function Foo is called with the specified arguments,
and with this bound to the newly created object. new Foo is equivalent
to new Foo(), i.e. if no argument list is specified, Foo is called
without arguments.
3) The object returned by the constructor function becomes the result of
the whole new expression. If the constructor function doesn't
explicitly return an object, the object created in step 1 is used
instead. (Normally constructors don't return a value, but they can
choose to do so if they want to override the normal object creation
process.)
Furthermore, from https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Inheritance:
We need to do one more thing before we move on. After adding the last
line, Teacher.prototype's constructor property is now equal to
Person(), because we just set Teacher.prototype to reference an object
that inherits its properties from Person.prototype! Try saving your
code, loading the page in a browser, and entering
Teacher.prototype.constructor into the console to verify.
In my example below customPrototype inherits its properties from Object.prototype as far as I can tell and so once I reassign Person.prototype to that it should change the constructor as well. And logging it I see that the constructor does change!
// Some custom object to inherit
var customPrototype = {
name: "XYZ"
};
// Person has its prototype object pointing to Object.prototype
var Person = function() {
this.name = "Not XYZ";
};
// Prints function() {this.name = "Not XYZ";}
console.log(Person.prototype.constructor);
// Change Person prototype to point to the custom prototype object
Person.prototype = customPrototype;
// Prints function Object() { [native code] }
console.log(Person.prototype.constructor);
var p = new Person();
// Prints Not XYZ
console.log(p.name);
Given the example above I expected the last name to print XYZ because nothing would be overwritten from the customPrototype object.
What am I missing? Why does it still call the Person function when (I think) it should be calling the Object.prototype.constructor?

Prototype.constructor have nothing to do with object initialization. When you want to create an object, you call new Person(), which actually calls the Person function, passes the object as the context (this) into the function and returns that object. Person function is called, no matter what prototype you have for it. And because in this function you have a property name set to Not XYZ, it will have that value. It shadows the prototype property with the same name. If you will delete this property from the object and try to again access name, you will get the prototypes one.
var customPrototype = {
name: "XYZ"
};
var Person = function() {
this.name = "Not XYZ";
};
Person.prototype = customPrototype;
var p = new Person();
console.log(p.name);
delete p.name;
console.log(p.name);
We set the prototype.constructor to keep the precise construction of the object and if we want to have some checkings based on which type of the object is.
Implementing copy logic for the objects of the type Person.
function Person(name) {
this.name = name;
};
Person.prototype.copy = function() {
return new this.constructor(this.name); // Access by `constructor` property, it is not necessary to call directly `Person`
}
const person = new Person('Bob');
console.log(person.name);
const secondPerson = person.copy();
console.log(secondPerson.name);
console.log(person === secondPerson);

Related

JavaScript: Constructor vs Prototype

This has been answered before, but I wanted to confirm my understanding. In this code:
var somePrototype = {
speak: function() {
console.log("I was made with a prototype");
}
}
function someConstructor() {
this.speak = function() {
console.log("I was made with a constructor");
}
}
var obj1 = Object.create(somePrototype);
var obj2 = new someConstructor();
obj1.speak();
obj2.speak();
They are both fundamentally doing the same thing, correct? The only difference is that the function someConstructor() is hoisted, meaning I can call new instances of it before it is defined, if needed, while the var somePrototype can only be called after it's been defined. Other than that, there's no difference?
The differences between 2 approaches (using Object.create() and constructor invocation) are:
The creation:
Object.create(somePrototype) creates a new object making the somePrototype it's prototype;
new someConstructor() creates an object using constructor invocation. The prototype of the obj2 is a simple object: new Object()
The properties inheritance:
obj1 inherits the property speak, which is a function. If this property changes in the somePrototype object, this will affect any objects created with Object.create(somePrototype) which inherit it.
Object.keys(obj1) will return [], because the object has no own properties.
obj2 contains an own property speak. Modifying this property on a single instance won't affect any other instances created using new someConstructor().
Object.keys(obj2) will return ['speak'] as its listed property.
The constructor:
obj1.constructor === Object is true
obj2.constructor === someConstructor is true
Hoisting:
someConstructor is hoisted to the top of scope it was created. So it can be used before the function declaration.
And sure somePrototype is not hoisted with the object literal, so should be used after setting up the value.
Check this interesting post about constructor property.
The Object.create() call creates an object and gives it the prototype you requested. The new call creates an object that's directly decorated by that constructor function.
The difference is that the object created by the constructor has an own property whose value is that function with the console.log(). The Object.create() call creates an object that inherits a similar function from the prototype object.
If you passed the first object to Object.keys(), you wouldn't see the "speak" property; if you passed the second object, you would.

The prototype property and inheritance in JavaScript

The prototype property and inheritance in JavaScript is not clear to me.
I have a function:
function User (name) {
this.name = name;
}
Questions:
1) Why one of the following is false and the other is true?
User.prototype.hasOwnProperty('name'); // false
User.hasOwnProperty('name'); // true
2) What is de difference between the followings:
User.constructor;
User.prototype.constructor;
3) What happens with the User.constructor and User.prototype.constructor if I override the prototype property like this:
User.prototype = {
changeName: function(newName) {
this.name = newName;
}
};
And what if I override it like this:
User.prototype = {
constructor: User,
changeName: function(newName) {
this.name = newName;
}
};
4) Is User a function or a prototype or what? The following site refers it as prototype: 'The following example creates a prototype ...'
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor
Thank you very much for your answers.
First you need to understand what a prototype is.
In Javascript, almost everything is an object.
Edit (thanks #Mathletics):
Primitive booleans, numbers, and strings are not objects
When you create an object in Javascript, by default, its prototype will be an Object.
So, if I do:
var obj = {};
console.log(obj.__proto__)
This yields:
Object {}
Pause:
To understand the difference between obj.prototype and obj.__proto__, please, refer to this thread.
The next step is to understand the concept of prototype chaining.
This is how inheritance is structured in Javascript. Basically, a prototype is the "parent" of another object, from which it derives methods and properties.
Imagine a scheme where a Rabbit inherits from Mammal, which inherits from Animal. Representing this in Javascript prototype chain would be like:
(Rabbit) -> (Mammal) -> (Animal) -> (Object) -> null
With code:
function Animal(){}
function Mammal(){}
function Rabbit(){}
Mammal.prototype = new Animal();
Rabit.prototype = new Mammal();
If you are able to understand these concepts, you might find the answers to your questions yourself, but I'll try to make it clearer:
1) why one of the following is false and the other is true?
User.prototype.hasOwnProperty('name'); // false
User.hasOwnProperty('name'); // true
You should read the hasOwnProperty method reference:
Every object descended from Object inherits the hasOwnProperty method. This method can be used to determine whether an object has the specified property as a direct property of that object[...]
This is a way to assure that the property you are looking for is defined within the object itself, not deeper in the prototype chain.
A contrary example would be:
console.log(User.hasOwnProperty('constructor'));
Since the constructor property is defined deeper in the prototype chaing, it is not an "own property" of User object.
In your case, name is a property defined within your User object, but not defined in the context of the global Object.
2) what is de difference between the followings:
User.constructor;
User.prototype.constructor;
The fist like takes the constructor of User, the second takes the constructor of its prototype (in this case, the global Object).
3) what happens with the User.constructor and
User.prototype.constructor if I override the prototype property like
this:
User.prototype = {
changeName: function(newName) {
this.name = newName;
}
};
Please, read this thread.
TL;DR: when you assing directly to the prototype, you are breaking the prototype chain an creating a new one. In the Rabbit example, if you at some point did:
Rabbit.prototype = {
// ...
};
Your new prototype chain would be:
(Rabbit) -> (Object) -> null
So, in your first example, User.prototype.constructor would yield:
function Object{}
In your second example, it would yield:
function User(name)
Got it?
4) is User a function or a prototype or what?
User is an object whose prototype is a Function object, whose prototype is a Object object.
Drawing it:
(User) -> (Function) -> (Object) -> null
Hope I've been clear.
"Everything" in JS is an object.
So a function is a special type of object and that type of object has a property called name which is why User.hasOwnProperty("name") returns true. It has nothing to do with the property of the User object that same function can create. Try calling it something else and you will see this to be the case.
Any object derives from another object, namely it's prototype. The prototype of a function has a constructor property and __proto__ property but no name property.
So Ùser.prototype.hasOwnProperty("name")` should return false
Since all properties of the prototype are derived you can do this User.constructor even though User.hasOwnProperty("constructor") would return false
1) why one of the following is false and the other is true?
User.prototype.hasOwnProperty('name'); // false, A
User.hasOwnProperty('name'); // true, B
The prototype object hasn't been given a name property and it doesn't have one by default (as User is not native), so this is false for the prototype.
The Constructor User is a Function and you've defined the name of the function as "User". This is set on the function object when it's interpreted.
Are you sure you're not confusing this with (new User('foo')).hasOwnProperty('name'); // true?
This last case, the instance of User has a name property which is "foo", as set by the constructor User.
2) what is de difference between the followings:
User.constructor;
User.prototype.constructor;
User.constructor is Function because User is a function.
User.prototype.constructor is undefined, but you'd normally reference it back at User. This is what would later be accessed as (new User).constructor; // User
3) what happens with the User.constructor and User.prototype.constructor if I override the prototype [...]
Nothing happens to User.constructor in either case.
As for User.prototype.constructor, it wasn't define previously
so remains undefined in the first case
is set to User in the second case
Please note that in both of these cases the entire prototype is now pointing at a different Object so existing instances will not see these changes and the previous prototype chain is no longer accessible to new instances.
4) is User a function or a prototype or what?
User is a function and is a constructor. In JavaScript we call certain functions constructors if they will be used to build (construct) instances.
It may be helpful for you to see a more abstract example,
// A function `Foo` which will be our Constructor
function Foo(baz) {
this.bar = baz;
}
// notice here we have `Foo.name; // "Foo"`
// Setting up reference to the constructor through the prototype
Foo.prototype.constructor = Foo;
// Setting up reference to some other shared property through the prototype
Foo.prototype.fizz = ['buzz'];
And then usage
var foo = new Foo('hello world');
foo.bar; // "hello world" (own)
foo.fizz; // ["buzz"] (inherited)
foo.constructor; // Foo (inherited)
var bar = new Foo();
foo.fizz === bar.fizz; // true, this is the same Object reference - it is shared
Don't be afraid to try things out in your Console!
Javascript, unlike other languages (Java, ecc.), isn't class-based, it doesn't provide any way to define a class (actually, the next Javascript, ES6-Harmony, introduces the class keyword but it's just a syntactic sugar on top of prototype inheritance and, at the moment, isn't available in any browser)...
So, Javascript implements the (aka) OOP (Object Oriented Programming) via Prototype Inheritance.
If you want to create a custom object, you need to use a function that defines it. Example:
var Person = (function() {
/**
* this is the Constructor (if you have in mind a class-based language)
**/
function Person() {}
return Person;
})(window);
Doing that we have defined a New Object Person and we can have multiple instances of it using the new operator:
var me = new Person();
var you = new Person();
//...
As all languages do, javascript objects can have Methods and Properties, methods and properties can be both of Instance and Class.
var Person = (function() {
function Person() {}
/**
* Static Method
**/
Person.sayCiao = function() {};
/**
* Static Property
**/
Person.ciao = 'Ciao';
/**
* Instance Method
**/
Person.prototype.sayHello = function() {};
/**
* Instance Property
**/
Person.prototype.hello = 'Hello';
return Person;
})(window);
As you can see (try in your console), using the prototype property we can define methods or properties that all objects created by calling new Person inherit.
1) why one of the following is false and the other is true?
Of course, statics methods or properties don't belong to the instance and hasOwnProperty returns true only when is called using the constructor function. Viceversa, instances methods or properties belong only to their instances and hasOwnProperty returns true only when is called using the new operator. This is the normal behaviour that you can meet in other programming languages.
Note: in ES6 the Function Object has a property name and this is the reason how your test returns true, but isn't referenced to the name property that you define in the Person Constructor (read more).
Example of usage:
var Person = (function() {
function Person(name) {
this.firstname = name
}
Person.prototype.firstname = '';
Person.factory = function(name) {
return new Person(name);
};
return Person;
})(window);
var hitmands = Person.factory('Giuseppe');
console.log('you are', hitmands);
var you = Person.factory('BatMan');
console.log('hitmands is', you);
console.info('Person has a name?', Person.hasOwnProperty('firstname'));
console.info('You have a name?', you.hasOwnProperty('firstname'));
The property prototype belongs to the prototype chain, this is the reason how your test return false... ({}).hasOwnProperty('prototype')... You can read more following this link.
Simply prototype and what it contains doesn't is own property of your object.
2) what is de difference between the followings (ecc.)
As someone said, one belongs to the function and the other to the prototype property.
3) what happens with the User.constructor and User.prototype.constructor if I override the prototype property like this (ecc.)
You can use that way to extend behaviour from one class to another...
Read more about this.

What's the difference between var p = new Person() and var p = Person()? [duplicate]

The new keyword in JavaScript can be quite confusing when it is first encountered, as people tend to think that JavaScript is not an object-oriented programming language.
What is it?
What problems does it solve?
When is it appropriate and when not?
It does 5 things:
It creates a new object. The type of this object is simply object.
It sets this new object's internal, inaccessible, [[prototype]] (i.e. __proto__) property to be the constructor function's external, accessible, prototype object (every function object automatically has a prototype property).
It makes the this variable point to the newly created object.
It executes the constructor function, using the newly created object whenever this is mentioned.
It returns the newly created object, unless the constructor function returns a non-null object reference. In this case, that object reference is returned instead.
Note: constructor function refers to the function after the new keyword, as in
new ConstructorFunction(arg1, arg2)
Once this is done, if an undefined property of the new object is requested, the script will check the object's [[prototype]] object for the property instead. This is how you can get something similar to traditional class inheritance in JavaScript.
The most difficult part about this is point number 2. Every object (including functions) has this internal property called [[prototype]]. It can only be set at object creation time, either with new, with Object.create, or based on the literal (functions default to Function.prototype, numbers to Number.prototype, etc.). It can only be read with Object.getPrototypeOf(someObject). There is no other way to get or set this value.
Functions, in addition to the hidden [[prototype]] property, also have a property called prototype, and it is this that you can access, and modify, to provide inherited properties and methods for the objects you make.
Here is an example:
ObjMaker = function() { this.a = 'first'; };
// `ObjMaker` is just a function, there's nothing special about it
// that makes it a constructor.
ObjMaker.prototype.b = 'second';
// like all functions, ObjMaker has an accessible `prototype` property that
// we can alter. I just added a property called 'b' to it. Like
// all objects, ObjMaker also has an inaccessible `[[prototype]]` property
// that we can't do anything with
obj1 = new ObjMaker();
// 3 things just happened.
// A new, empty object was created called `obj1`. At first `obj1`
// was just `{}`. The `[[prototype]]` property of `obj1` was then set to the current
// object value of the `ObjMaker.prototype` (if `ObjMaker.prototype` is later
// assigned a new object value, `obj1`'s `[[prototype]]` will not change, but you
// can alter the properties of `ObjMaker.prototype` to add to both the
// `prototype` and `[[prototype]]`). The `ObjMaker` function was executed, with
// `obj1` in place of `this`... so `obj1.a` was set to 'first'.
obj1.a;
// returns 'first'
obj1.b;
// `obj1` doesn't have a property called 'b', so JavaScript checks
// its `[[prototype]]`. Its `[[prototype]]` is the same as `ObjMaker.prototype`
// `ObjMaker.prototype` has a property called 'b' with value 'second'
// returns 'second'
It's like class inheritance because now, any objects you make using new ObjMaker() will also appear to have inherited the 'b' property.
If you want something like a subclass, then you do this:
SubObjMaker = function () {};
SubObjMaker.prototype = new ObjMaker(); // note: this pattern is deprecated!
// Because we used 'new', the [[prototype]] property of SubObjMaker.prototype
// is now set to the object value of ObjMaker.prototype.
// The modern way to do this is with Object.create(), which was added in ECMAScript 5:
// SubObjMaker.prototype = Object.create(ObjMaker.prototype);
SubObjMaker.prototype.c = 'third';
obj2 = new SubObjMaker();
// [[prototype]] property of obj2 is now set to SubObjMaker.prototype
// Remember that the [[prototype]] property of SubObjMaker.prototype
// is ObjMaker.prototype. So now obj2 has a prototype chain!
// obj2 ---> SubObjMaker.prototype ---> ObjMaker.prototype
obj2.c;
// returns 'third', from SubObjMaker.prototype
obj2.b;
// returns 'second', from ObjMaker.prototype
obj2.a;
// returns 'first', from SubObjMaker.prototype, because SubObjMaker.prototype
// was created with the ObjMaker function, which assigned a for us
I read a ton of rubbish on this subject before finally finding this page, where this is explained very well with nice diagrams.
Suppose you have this function:
var Foo = function(){
this.A = 1;
this.B = 2;
};
If you call this as a stand-alone function like so:
Foo();
Executing this function will add two properties to the window object (A and B). It adds it to the window because window is the object that called the function when you execute it like that, and this in a function is the object that called the function. In JavaScript at least.
Now, call it like this with new:
var bar = new Foo();
When you add new to a function call, a new object is created (just var bar = new Object()) and the this within the function points to the new Object you just created, instead of to the object that called the function. So bar is now an object with the properties A and B. Any function can be a constructor; it just doesn't always make sense.
In addition to Daniel Howard's answer, here is what new does (or at least seems to do):
function New(func) {
var res = {};
if (func.prototype !== null) {
res.__proto__ = func.prototype;
}
var ret = func.apply(res, Array.prototype.slice.call(arguments, 1));
if ((typeof ret === "object" || typeof ret === "function") && ret !== null) {
return ret;
}
return res;
}
While
var obj = New(A, 1, 2);
is equivalent to
var obj = new A(1, 2);
For beginners to understand it better
Try out the following code in the browser console.
function Foo() {
return this;
}
var a = Foo(); // Returns the 'window' object
var b = new Foo(); // Returns an empty object of foo
a instanceof Window; // True
a instanceof Foo; // False
b instanceof Window; // False
b instanceof Foo; // True
Now you can read the community wiki answer :)
so it's probably not for creating
instances of object
It's used exactly for that. You define a function constructor like so:
function Person(name) {
this.name = name;
}
var john = new Person('John');
However the extra benefit that ECMAScript has is you can extend with the .prototype property, so we can do something like...
Person.prototype.getName = function() { return this.name; }
All objects created from this constructor will now have a getName because of the prototype chain that they have access to.
JavaScript is an object-oriented programming language and it's used exactly for creating instances. It's prototype-based, rather than class-based, but that does not mean that it is not object-oriented.
Summary:
The new keyword is used in JavaScript to create a object from a constructor function. The new keyword has to be placed before the constructor function call and will do the following things:
Creates a new object
Sets the prototype of this object to the constructor function's prototype property
Binds the this keyword to the newly created object and executes the constructor function
Returns the newly created object
Example:
function Dog (age) {
this.age = age;
}
const doggie = new Dog(12);
console.log(doggie);
console.log(Object.getPrototypeOf(doggie) === Dog.prototype) // true
What exactly happens:
const doggie says: We need memory for declaring a variable.
The assignment operator = says: We are going to initialize this variable with the expression after the =
The expression is new Dog(12). The JavaScript engine sees the new keyword, creates a new object and sets the prototype to Dog.prototype
The constructor function is executed with the this value set to the new object. In this step is where the age is assigned to the new created doggie object.
The newly created object is returned and assigned to the variable doggie.
Please take a look at my observation on case III below. It is about what happens when you have an explicit return statement in a function which you are newing up. Have a look at the below cases:
Case I:
var Foo = function(){
this.A = 1;
this.B = 2;
};
console.log(Foo()); //prints undefined
console.log(window.A); //prints 1
Above is a plain case of calling the anonymous function pointed by variable Foo. When you call this function it returns undefined. Since there isn’t any explicit return statement, the JavaScript interpreter forcefully inserts a return undefined; statement at the end of the function. So the above code sample is equivalent to:
var Foo = function(){
this.A = 1;
this.B = 2;
return undefined;
};
console.log(Foo()); //prints undefined
console.log(window.A); //prints 1
When Foo function is invoked window is the default invocation object (contextual this) which gets new A and B properties.
Case II:
var Foo = function(){
this.A = 1;
this.B = 2;
};
var bar = new Foo();
console.log(bar()); //illegal isn't pointing to a function but an object
console.log(bar.A); //prints 1
Here the JavaScript interpreter, seeing the new keyword, creates a new object which acts as the invocation object (contextual this) of anonymous function pointed by Foo. In this case A and B become properties on the newly created object (in place of window object). Since you don't have any explicit return statement, JavaScript interpreter forcefully inserts a return statement to return the new object created due to usage of new keyword.
Case III:
var Foo = function(){
this.A = 1;
this.B = 2;
return {C:20,D:30};
};
var bar = new Foo();
console.log(bar.C);//prints 20
console.log(bar.A); //prints undefined. bar is not pointing to the object which got created due to new keyword.
Here again, the JavaScript interpreter, seeing the new keyword, creates a new object which acts as the invocation object (contextual this) of anonymous function pointed by Foo. Again, A and B become properties on the newly created object. But this time you have an explicit return statement so JavaScript interpreter will not do anything of its own.
The thing to note in case III is that the object being created due to new keyword got lost from your radar. bar is actually pointing to a completely different object which is not the one which JavaScript interpreter created due to the new keyword.
Quoting David Flanagan from JavaScript: The Definitive Guide (6th Edition), Chapter 4, Page # 62:
When an object creation expression is evaluated, JavaScript first
creates a new empty object, just like the one created by the object
initializer {}. Next, it invokes the specified function with the
specified arguments, passing the new object as the value of the this
keyword. The function can then use this to initialize the properties
of the newly created object. Functions written for use as constructors
do not return a value, and the value of the object creation expression
is the newly created and initialized object. If a constructor does
return an object value, that value becomes the value of the object
creation expression and the newly created object is discarded.
Additional information:
The functions used in the code snippet of the above cases have special names in the JavaScript world as below:
Case #
Name
Case I
Constructor function
Case II
Constructor function
Case III
Factory function
You can read about the difference between constructor functions and factory functions in this thread.
Code smell in case III - Factory functions should not be used with the new keyword which I've shown in the code snippet above. I've done so deliberately only to explain the concept.
JavaScript is a dynamic programming language which supports the object-oriented programming paradigm, and it is used for creating new instances of objects.
Classes are not necessary for objects. JavaScript is a prototype-based language.
The new keyword changes the context under which the function is being run and returns a pointer to that context.
When you don't use the new keyword, the context under which function Vehicle() runs is the same context from which you are calling the Vehicle function. The this keyword will refer to the same context. When you use new Vehicle(), a new context is created so the keyword this inside the function refers to the new context. What you get in return is the newly created context.
Sometimes code is easier than words:
var func1 = function (x) { this.x = x; } // Used with 'new' only
var func2 = function (x) { var z={}; z.x = x; return z; } // Used both ways
func1.prototype.y = 11;
func2.prototype.y = 12;
A1 = new func1(1); // Has A1.x AND A1.y
A2 = func1(1); // Undefined ('this' refers to 'window')
B1 = new func2(2); // Has B1.x ONLY
B2 = func2(2); // Has B2.x ONLY
For me, as long as I do not prototype, I use the style of func2 as it gives me a bit more flexibility inside and outside the function.
Every function has a prototype object that’s automatically set as the prototype of the objects created with that function.
You guys can check easily:
const a = { name: "something" };
console.log(a.prototype); // 'undefined' because it is not directly accessible
const b = function () {
console.log("somethign");
};
console.log(b.prototype); // Returns b {}
But every function and objects has the __proto__ property which points to the prototype of that object or function. __proto__ and prototype are two different terms. I think we can make this comment: "Every object is linked to a prototype via the proto" But __proto__ does not exist in JavaScript. This property is added by browser just to help for debugging.
console.log(a.__proto__); // Returns {}
console.log(b.__proto__); // Returns [Function]
You guys can check this on the terminal easily. So what is a constructor function?
function CreateObject(name, age) {
this.name = name;
this.age = age
}
Five things that pay attention first:
When the constructor function is invoked with new, the function’s internal [[Construct]] method is called to create a new instance object and allocate memory.
We are not using return keyword. new will handle it.
The name of the function is capitalized, so when developers see your code they can understand that they have to use the new keyword.
We do not use the arrow function. Because the value of the this parameter is picked up at the moment that the arrow function is created which is "window". Arrow functions are lexically scoped, not dynamically. Lexically here means locally. The arrow function carries its local "this" value.
Unlike regular functions, arrow functions can never be called with the new keyword, because they do not have the [[Construct]] method. The prototype property also does not exist for arrow functions.
const me = new CreateObject("yilmaz", "21")
new invokes the function and then creates an empty object {} and then adds "name" key with the value of "name", and "age" key with the value of argument "age".
When we invoke a function, a new execution context is created with "this" and "arguments", and that is why "new" has access to these arguments.
By default, this inside the constructor function will point to the "window" object, but new changes it. "this" points to the empty object {} that is created and then properties are added to newly created object. If you had any variable that defined without "this" property will no be added to the object.
function CreateObject(name, age) {
this.name = name;
this.age = age;
const myJob = "developer"
}
myJob property will not added to the object because there is nothing referencing to the newly created object.
const me = {name: "yilmaz", age: 21} // There isn't any 'myJob' key
In the beginning I said every function has a "prototype" property, including constructor functions. We can add methods to the prototype of the constructor, so every object that created from that function will have access to it.
CreateObject.prototype.myActions = function() { /* Define something */ }
Now "me" object can use the "myActions" method.
JavaScript has built-in constructor functions: Function, Boolean, Number, String, etc.
If I create
const a = new Number(5);
console.log(a); // [Number: 5]
console.log(typeof a); // object
Anything that is created by using new has the type of object. Now "a" has access all of the methods that are stored inside Number.prototype. If I defined
const b = 5;
console.log(a === b); // 'false'
a and b are 5 but a is object and b is primitive. Even though b is primitive type, when it is created, JavaScript automatically wraps it with Number(), so b has access to all of the methods that inside Number.prototype.
A constructor function is useful when you want to create multiple similar objects with the same properties and methods. That way you will not be allocating extra memory so your code will run more efficiently.
The new keyword is for creating new object instances. And yes, JavaScript is a dynamic programming language, which supports the object-oriented programming paradigm. The convention about the object naming is: always use a capital letter for objects that are supposed to be instantiated by the new keyword.
obj = new Element();
JavaScript is not an object-oriented programming (OOP) language. Therefore the look up process in JavaScript works using a delegation process, also known as prototype delegation or prototypical inheritance.
If you try to get the value of a property from an object that it doesn't have, the JavaScript engine looks to the object's prototype (and its prototype, one step above at a time).
It's prototype chain until the chain ends up to null which is Object.prototype == null (Standard Object Prototype).
At this point, if the property or method is not defined then undefined is returned.
Important! Functions are are first-class objects.
Functions = Function + Objects Combo
FunctionName.prototype = { shared SubObject }
{
// other properties
prototype: {
// shared space which automatically gets [[prototype]] linkage
when "new" keyword is used on creating instance of "Constructor
Function"
}
}
Thus with the new keyword, some of the task that were manually done, e.g.,
Manual object creation, e.g., newObj.
Hidden bond creation using proto (AKA: dunder proto) in the JavaScript specification [[prototype]] (i.e., proto)
referencing and assign properties to newObj
return of the newObj object.
All is done manually.
function CreateObj(value1, value2) {
const newObj = {};
newObj.property1 = value1;
newObj.property2 = value2;
return newObj;
}
var obj = CreateObj(10,20);
obj.__proto__ === Object.prototype; // true
Object.getPrototypeOf(obj) === Object.prototype // true
JavaScript keyword new helps to automate this process:
A new object literal is created identified by this:{}
referencing and assign properties to this
Hidden bond creation [[prototype]] (i.e. proto) to Function.prototype shared space.
implicit return of this object {}
function CreateObj(value1, value2) {
this.property1 = value1;
this.property2 = value2;
}
var obj = new CreateObj(10,20);
obj.__proto__ === CreateObj.prototype // true
Object.getPrototypeOf(obj) == CreateObj.prototype // true
Calling a constructor function without the new keyword:
=> this: Window
function CreateObj(value1, value2) {
var isWindowObj = this === window;
console.log("Is Pointing to Window Object", isWindowObj);
this.property1 = value1;
this.property2 = value2;
}
var obj = new CreateObj(10,20); // Is Pointing to Window Object false
var obj = CreateObj(10,20); // Is Pointing to Window Object true
window.property1; // 10
window.property2; // 20
The new keyword creates instances of objects using functions as a constructor. For instance:
var Foo = function() {};
Foo.prototype.bar = 'bar';
var foo = new Foo();
foo instanceof Foo; // true
Instances inherit from the prototype of the constructor function. So given the example above...
foo.bar; // 'bar'
Well, JavaScript per se can differ greatly from platform to platform as it is always an implementation of the original specification ECMAScript (ES).
In any case, independently of the implementation, all JavaScript implementations that follow the ECMAScript specification right, will give you an object-oriented language. According to the ES standard:
ECMAScript is an object-oriented programming language for
performing computations and manipulating computational objects
within a host environment.
So now that we have agreed that JavaScript is an implementation of ECMAScript and therefore it is an object-oriented language. The definition of the new operation in any object-oriented language, says that such a keyword is used to create an object instance from a class of a certain type (including anonymous types, in cases like C#).
In ECMAScript we don't use classes, as you can read from the specifications:
ECMAScript does not use classes such as those in C++, Smalltalk, or Java. Instead objects may be created in various ways including via
a literal notation or via constructors which create objects and then execute code that initializes all or part of them by assigning initial
values to their properties. Each constructor is a function that has a
property named ―
prototype ‖ that is used to implement prototype - based inheritance and shared properties. Objects are created by
using constructors in new expressions; for example, new
Date(2009,11) creates a new Date object. Invoking a constructor
without using new has consequences that depend on the constructor.
For example, Date() produces a string representation of the
current date and time rather than an object.
It has 3 stages:
1.Create: It creates a new object, and sets this object's [[prototype]] property to be the prototype property of the constructor function.
2.Execute: It makes this point to the newly created object and executes the constructor function.
3.Return: In normal case, it will return the newly created object. However, if you explicitly return a non-null object or a function , this value is returned instead. To be mentioned, if you return a non-null value, but it is not an object(such as Symbol value, undefined, NaN), this value is ignored and the newly created object is returned.
function myNew(constructor, ...args) {
const obj = {}
Object.setPrototypeOf(obj, constructor.prototype)
const returnedVal = constructor.apply(obj, args)
if (
typeof returnedVal === 'function'
|| (typeof returnedVal === 'object' && returnedVal !== null)) {
return returnedVal
}
return obj
}
For more info and the tests for myNew, you can read my blog: https://medium.com/#magenta2127/how-does-the-new-operator-work-f7eaac692026

Inheritance within Javascript

I'm studying the concept of inheritance in Javascript, and the tutorial I'm looking at uses this code:
// define the Student class
function Student() {
// Call the parent constructor
Person.call(this);
}
// inherit Person
Student.prototype = new Person();
// correct the constructor pointer because it points to Person
Student.prototype.constructor = Student;
My question is, why is it necessary to both call the parent constructor, Person.call(this), and set the Student prototype equal to a new Person object (i.e. Student.prototype = new Person();)?
There are two separate issues to deal with.
The first is to make sure new Student objects inherit from Person objects. That's why you do Student.prototype = new Person(). That makes the Student.prototype a Person so Student objects will inherit whatever that object inherits (from Person.prototype).
The second is to apply any behavior in the Person constructor to any new Student objects. That's why you do Person.call(this). This is technically not needed if the Person constructor doesn't have any code that modifies the new object, but it's still a good idea to do it just in case you add some code to Person later.
Side note, when setting up the inheritance, it's better to do:
Student.prototype = Object.create(Person.prototype)
...and shim Object.create if needed. This way you don't actually need to invoke the Person constructor in order to get a new object that inherits from Person.prototype. Again, sometimes not an issue, but sometimes there are side effects in the constructor that are undesired when setting up the inheritance.
After doing some testing, to my understanding, the prototype of an object and the property declarations made within its defining function are separate. However, when one constructs a new object, the constructor will pull properties from both the defining function and the prototype of the object being created.
For example,
function Person()
{
this.name = "james";
this.age = "shfifty-five";
}
console.log(Person.prototype.name); // prints "undefined", showing how declaring function Person() and Person.prototype are separate.
Person.prototype.gender = "male";
var human = new Person();
console.log(human.name); // prints "james", showing how the object took properties from declaring function Person().
console.log(human.gender); // prints "male", showing how the object took properties from object prototype Person.prototype.
function Student()
{
this.gpa = 4.00;
}
Student.prototype = new Person();
Student.prototype.constructor = Student;
var myStudent = new Student();
console.log(myStudent.name); // prints "james"
console.log(myStudent.gender); // prints "male"
/*from above two lines, inheritance holds even though 1) Person() defining function was not called inside Student() defining function
and 2) Person() defining function declares properties of Person object.*/
console.log(myStudent.gpa); // prints "4"
As you can see, in this case the defining function Person does alter the properties of its object. But it is still not necessary to call the Person function within the constructor of Student, because the new Person() constructor will pull properties from both Person.prototype and the function Person() defining function.

javascript function object and this

What's difference of this in the following two cases?
Case 1
var Person = function() { this.name="Allen Kim" }
Person.name; //undefined
Case 2
var Person = function() { this.name="Allen Kim" }
var me = new Person();
me.name // Allen Kim
Just wanted to understand how this scope works on both cases.
Every function in JavaScript is itself an object. So Person.name retrieves the name property from the function itself, which was never set; hence undefined.
You can try this my setting it directly:
Person.name = "John";
Person.name; // "John"
When assigning a property from within the constructor via
this.name = "Allen Kim";
you're setting the property on that instance. When you then instantiate an object with:
var me = new Person();
your constructor will add the name property to me, since this referes to the object being created.
Here are the basic steps taken by the JavaScript engine when calling a constructor function with the new keyword:
Calls the constructor with this set to a new clean object.
Sets the internal [[Prototype]] property of your new object to the constructor's prototype (which, in some implementations, is then available through __proto__).
Sets up the constructor property of your new object as a reference to the constructor function (so instead of the non-standard me.__proto__, you could access the prototype via me.constructor.prototype).
Returns said object.
Note that this is a very basic explanation. There are many other things not included here, but this should give you the gist of it.
On the first case you are looking for a static property on the function itself.
The second case you are returning an instance of an object that has the property by calling a constructor function. Its not really a matter of scope.
var Person = function() { this.name="Allen Kim" }
Person.name; //undefined due to the fact that there is no Person object.
var Person = function() { this.name="Allen Kim" }
var me = new Person();
me.name // Allen Kim --> Person `me`'s name

Categories

Resources