I'm not exactly sure how to ask this question, so I'll do it by example. Say I have this set up:
var x = function() {
console.log('YAY!');
};
x.test0 = 0;
x.test1 = 1;
x.test2 = "hello world";
that works as expected:
x(); // YAY!
x.test0 // 0
x.test2 // "hello world"
Now, I would like to know how to set this up starting with an object first. I tried adding the function using constructor, but that doesn't work.
var x = {
test0 : 0,
test1 : 1,
test2 : 'hello world',
constructor: function() {
console.log('YAY!');
}
}
x(); // object is not a function
x.test0 // 0
x.test2 // "hello world";
I've tried other crazy things, but nothing seems to work.
Any ideas? Or am I stuck doing it the first way?
As demonstrated by your first example, functions in JavaScript are objects and can have properties.
ECMAScript defines "internal properties" (and internal methods) for objects. These internal properties help define the state of an object, but not all of an object's internal properties are directly settable from code. We denote an internal property name with double square brackets, like [[Foo]].
When you call a function like foo(), you run the object's [[Call]] internal method. However, only function objects have a [[Call]] internal method. It is not possible to set or change a non-host object's [[Call]] method; it is set when the object is defined and there is no mechanism defined by ECMAScript to change it. ("Host" objects are objects supplied by the browser or other execution environment and can play by different rules. Unless you're writing a browser, you probably don't need to consider this exception.)
Thus, if you define a function
foo = function() { doStuff(); return 5; };
that function (which is assigned to the variable foo) has a permanent [[Call]] method (per the function-creation rules in section 13.2), which runs doStuff and returns 5.
If you have a non-function object
foo = { };
that object is lacking a [[Call]] property. There is no way to give it a [[Call]] property, because non-host objects can only set [[Call]] at definition-time. The logical internal property [[Call]] does not correspond to any object property accessible in actual code.
In sum, making a non-function object callable is not possible. If you want an object to be callable, define it initially as a function, as you do in your first example.
To put it simply you can't. Why? because the types of both the objects are different first a Function Object and second returns a standard object. So both inherits from different ancestors. The only possibility here is if you can cast object to a function and there's no such thing available n JavaScript natively. However you can use your own cast method.
function toFunction (obj, fnProp) {
var fn = function () {};
if (typeof obj[fnProp] !== 'function') return fn;
else {
fn = obj[fnProp];
for (prop in obj) {
fn[prop] = obj[prop];
}
}
return fn;
}
var z = toFunction(y, 'prototype'); // with your example
You can't just create an object and later run it as if it were a function.
You can do it the other way around, as in JavaScript a function is an object:
x.prop=1;
console.log(x.prop);
function x() {
return true;
}
Did not got exactly what you want, do you want something like object oriented? This may help
function x(){
this.test0 = 0;
this.test1 = 1;
this.test2 = 'hello word';
console.log('Wow!');
}
var y = new x(); // new object of x PRINTS WOW and set's default values
console.log(y.test0) // 0
console.log(y.test2) // "hello world";
Related
Im new to javascript ; and im digging into 'new' variable.
My qustion is :
function Fruit(name)
{
this.name = name;
}
function myNew(con,args){
var obj = {};
obj = con.apply(obj,args) || obj;
obj.constructor = con;
return obj;
}
var f1 = new Fruit("Mango");
var f2 = myNew(Fruit,["Orange"]);
console.log(f1.name, f1 instanceof Fruit);
console.log(f2.name, f2 instanceof Fruit);
now the output im getting is :
Mango true
Orange false
what I need to do if I need output :
Mango true
Orange true..
I need some explanation here.
I dont know if somebody already answered this question but i was unable to find it.
Lets say we have Foo constructor.
function Foo(options) {
// constructor
this.name = options.name;
}
// and create instance of it
var foo = new Foo({name: "Foo"});
From the MDN reference, "new" operator does:
A new object is created, inheriting from Foo.prototype.
The constructor function Foo is called with the specified arguments and 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.
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.)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new
So basically it setups object prototype and executes constructor function, returning an object, unless constructor doesn't return anything else.
"apply" function instend, only runs function in specific context. It doesn't setup inheritance. In you case it just runs constructor in context of your custom obj.
var obj = {};
You can see this on this fiddle:
http://jsfiddle.net/hp244jn7/
There "_ proto _" property used, to see whats in prototype chain. Don't use it in development.
If you want the desired effect you should probably use what giorgio suggested.
You should use prototype property to define that your object is based on some other object
function myNew(con,args){
var obj = {};
obj = con.apply(obj,args) || obj;
obj.prototype = con;
return obj;
}
You're thinking to difficult ;) This is doing what you want:
function myNew(con, args) {
return new con(args);
}
see the demo here
Consider the first scenario:
function f(){
console.log("inside the function : " + f.myVar);
}
f.prototype.myVar = 1;
var myObject = new f();
console.log("from the object : " + myObject.myVar);
And this is the output:
inside the function : undefined
from the object : 1
Question: why myVar isn't available in function? If it is stored in the objects prototype it is supposed to be accessible in f().
Now this scenario:
function f(){
console.log("inside the function : " + this.myVar);
}
f.prototype.myVar = 1;
var myObject = new f();
console.log("from the object : " + myObject.myVar);
And the output:
inside the function : 1
from the object : 1
Question: Why I'm getting different result? if 'this' refers to the object doesn't f.myVar mean access myVar in myObject ?
And now this scenario:
function f(){
console.log("inside the function : " + f.myVar);
console.log("inside the function using 'this' : " + this.myVar);
}
f.myVar = 1;
var myObject = new f();
console.log("from the object : " + myObject.myVar);
output:
inside the function : 1
inside the function using 'this' : undefined
from the object : undefined
So if I set a property without using prototype it should'nt be available in instantiated objects. But if I write the script like this, it'll deliver a strange result:
function f(){
console.log("inside the function : " + f.myVar);
}
f.myVar = 1;
var myObject = new f();
console.log("from the first object : " + myObject.myVar);
var strangeObject = myObject.constructor;
console.log("from the strange object : " + strangeObject.myVar);
Output:
inside the function : 1
from the first object : undefined
from the strange object : 1
Where does that "f.myVar" store? Whose variable is that? I'm confused what is the difference between all scenarios above. A complete carification would be much appreciated.
EDIT:
The main problem is that I don't know what this exactly mean:
function f(){}
f.someVar = someValue;
Because in other languages function is an abstract concept and in fact doesn't exist until it is called. Now in JS it is said that functions are objects by default. Ok so I should have an object like this by the script above:
{someVar : sameValue}
in fact I think this should be as same as:
function f(){this.someVar = someValue;} //should create {someVar : someValue}
If this is the case EVERY object instantiated by calling "new f()" must contain this "someVar" but they don't.
Start out by examining the definition of the word prototype. I think it's important to keep this in mind when thinking about how new objects are created in JavaScript.
pro·to·type
noun
a first, typical or preliminary model of something, especially a machine, from which other forms are developed or copied.
verb
make a prototype of (a product).
A prototype is a model from which another form will be copied.
When you create a new object in JavaScript, that is exactly what happens.
var obj = new MyObject();
In the above code, there are many things that happen, but in the context of the question, there are two things that happen which are relevant:
The prototype is applied to a new object.
The function MyObject is called, with this set to the new object.
With this knowledge in mind, let's take a look at the different forms of setting variables you have described:
function MyObject() {}
MyObject.myProperty = 'MyProperty';
It's important to understand that functions themselves are objects in JavaScript. Therefore, function MyObject is an object instance to itself. On the second line, we have set the property myProperty on this function object.
Refer back to the steps of creation above, and you will notice that it does not include applying properties from the function object to the new instance object. It only applies properties from the function object's prototype, and then runs the body of the function with this set to the new instance.
function MyObject() {
this.myProperty = 'MyProperty';
}
Here, the property myProperty is set on the individual instance.
function MyObject() {}
MyObject.prototype.myProperty = 'MyProperty';
In this example, each new instance of MyObject will be given its own property called myProperty and the value set to 'MyProperty'. From there, each instance can change its own myProperty to whatever value it needs without affecting the other.
function MyObject() {
console.log('myProperty', this.myProperty); //Will output 'Outside constructor.'
this.myProperty = 'Inside constructor.';
console.log('myProperty', this.myProperty); //Will output 'Inside constructor.
}
MyObject.prototype.myProperty = 'Outside constructor.';
The above example shows how myProperty is first applied from the prototype, then overwritten by the value applies in the function that is run.
Let's take a look at an example with all the forms you mentioned:
var output1 = document.getElementById('output1'),
output2 = document.getElementById('output2'),
output3 = document.getElementById('output3');
function MyObject(myProperty) {
this.myProperty = myProperty;
}
MyObject.myProperty = 'Function property.';
MyObject.prototype.myProperty = 'Prototype property.';
var obj = new MyObject('Constructor property');
output1.innerHTML = obj.myProperty;
output2.innerHTML = MyObject.myProperty;
output3.innerHTML = MyObject.prototype.myProperty;
<div id="output1"></div>
<div id="output2"></div>
<div id="output3"></div>
In the above example, you'll see how each can be referenced. Now examine it a little closer. Take a look at what happens with your 'Function property' when it is set from two different object instances:
var output1 = document.getElementById('output1'),
output2 = document.getElementById('output2');
function MyObject() {
//We are concatenating a string to the end of the property on each function call.
MyObject.myProperty += ' test ';
}
MyObject.myProperty = 'Function property.';
var obj1 = new MyObject();
var obj2 = new MyObject();
output1.innerHTML = MyObject.myProperty;
output2.innerHTML = MyObject.myProperty;
<div id="output1"></div>
<div id="output2"></div>
The above code demonstrates how the function level property is effectively shared. That's because it's not part of each instance. It's part of the function object.
Here I'll show you the process that takes place with the new operator, without actually using the new operator:
var output = document.getElementById('output');
//Let's have an object that has a prototype property with some properties:
var MyPrototypeObject = {
prototype: {
myPrototypeProperty: 'Prototype property'
}
};
//Let's specify a function that will be used as a constructor:
function MyConstructorFunction() {
this.myInstanceProperty = 'Instance property';
}
//First, new creates an object
var obj = {};
//Next, it applies all the properties from the prototype. We are using the MyPrototypeObject's prototype property for this example
for (var key in MyPrototypeObject.prototype) {
var val = MyPrototypeObject.prototype[key];
//Set the same property on the new object.
obj[key] = val;
}
//Now the prototype has been applied, let's apply the constructor function that was called.
MyConstructorFunction.call(obj); //This calls MyConstructorFunction with this set to obj.
output.innerHTML = 'myPrototypeProperty: ' + obj.myPrototypeProperty + '<br>' + 'myInstanceProperty: ' + obj.myInstanceProperty;
<div id="output"></div>
why myVar isn't available in function? If it is stored in the objects
prototype it is supposed to be accessible in f().
It's accessible in the function, but not as f.myVar, but as this.myVar or f.prototype.myVar.
Why I'm getting different result? if 'this' refers to the object
doesn't f.myVar mean access myVar in myObject ?
The function f is not the same as the object instance. The function is the constructor for the object, and using it with the new keyword creates an instance that is a separate object from the function.
When you use f.var, that is the property var of the function object. When you use this.var in the function, that is the property var in the object instance that the use of the new keyword created.
If you use f.var, that is a property of the constructor function object, so it will be the same variable even if you create multiple instances of the object, and it's only accessible using f.var.
If you use f.prototype.var, that will also be a variable that is the same for all instances of the object, but that can also be accessed using this.var as the object inherits the members of the prototype.
Example:
function f() {
console.log(f.var); // shows "42"
console.log(f.prototype.var); // shows "0.01"
console.log(this.var); shows "0.01";
}
f.var = 42;
f.prototype.var = 0.01;
If you want a variable that is local to each instance of the object, you should use neither of those. You should assign a value to this.var, which will make it a property in the object instance.
Example:
function f(value) {
this.var = value;
}
f.prototype.getValue = function(){
return this.var;
};
var instance1 = new f(42);
var instance2 = new f(0.01);
// now you have two instances with separate values:
console.log(instance1.getValue()); // shows "42"
console.log(instance2.getValue()); // shows "0.01"
As for question in edit, really all simple :-)
you have a function object function f(){}
you add to this object property, like you can add property to any other object in javascript f.someVar = 1
this not same as function f(){this.someVar = someValue;} because this in javascript depends on how function calling and can refers to created object, global object, or something else if called with call or apply function.
When you create object with new operator - you call f as constructor, and in this case this inside function referes to created object, and all properties added inside function as this.something = val add to created object.
Note: that you not use any property from function directly, so this not added to created object.
As for prototype: when you create object - you just set prototype property of created object to f.prototype object. So at end when you create object, you not use any property directly added to function object, just property from prototype and property that added manually to this in constructor
Seems you are getting confused with the prototype of function and object.
Here's a quote from the book Eloquent Javascript explaining the difference:
It is important to note the distinction between the way a prototype is
associated with a constructor (through its prototype property) and the
way objects have a prototype (which can be retrieved with
Object.getPrototypeOf). The actual prototype of a constructor is
Function.prototype since constructors are functions. Its prototype
property will be the prototype of instances created through it but is
not its own prototype.
With respect to JS, what's the difference between the two? I know methods are associated with objects, but am confused what's the purpose of functions? How does the syntax of each of them differ?
Also, what's the difference between these 2 syntax'es:
var myFirstFunc = function(param) {
//Do something
};
and
function myFirstFunc(param) {
//Do something
};
Also, I saw somewhere that we need to do something like this before using a function:
obj.myFirstFunc = myFirstFunc;
obj.myFirstFunc("param");
Why is the first line required, and what does it do?
Sorry if these are basic questions, but I'm starting with JS and am confused.
EDIT: For the last bit of code, this is what I'm talking about:
// here we define our method using "this", before we even introduce bob
var setAge = function (newAge) {
this.age = newAge;
};
// now we make bob
var bob = new Object();
bob.age = 30;
// and down here we just use the method we already made
bob.setAge = setAge;
To answer your title question as to what is the difference between a 'function' and a 'method'.
It's semantics and has to do with what you are trying to express.
In JavaScript every function is an object. An object is a collection of key:value pairs. If a value is a primitive (number, string, boolean), or another object, the value is considered a property. If a value is a function, it is called a 'method'.
Within the scope of an object, a function is referred to as a method of that object. It is invoked from the object namespace MyObj.theMethod(). Since we said that a function is an object, a function within a function can be considered a method of that function.
You could say things like “I am going to use the save method of my object.” And "This save method accepts a function as a parameter.” But you generally wouldn't say that a function accepts a method as a parameter.
Btw, the book JavaScript Patterns by Stoyan Stefanov covers your questions in detail, and I highly recommend it if you really want to understand the language. Here's a quote from the book on this subject:
So it could happen that a function A, being an object, has properties and methods, one of which happens to be another function B. Then B can accept a function C as an argument and, when executed, can return another function D.
There is a slight difference -
Method : Method is a function when object is associated with it.
var obj = {
name : "John snow",
work : function someFun(paramA, paramB) {
// some code..
}
Function : When no object is associated with it , it comes to function.
function fun(param1, param2){
// some code...
}
Many answers are saying something along the lines that a method is what a function is called when it is defined on an object.
While this is often true in the way the word is used when people talk about JavaScript or object oriented programming in general (see here), it is worth noting that in ES6 the term method has taken on a very specific meaning (see section 14.3 Method Definitions of the specs).
Method Definitions
A method (in the strict sense) is a function that was defined through the concise method syntax in an object literal or as a class method in a class declaration / expression:
// In object literals:
const obj = {
method() {}
};
// In class declarations:
class MyClass {
method() {}
}
Method Specificities
This answer gives a good overview about the specificities of methods (in the strict sense), namely:
methods get assigned an internal [[HomeObject]] property which allows them to use super.
methods are not created with a prototype property and they don't have an internal [[Construct]] method which means that they cannot be called with new.
the name of a method does not become a binding in the method's scope.
Below are some examples illustrating how methods (in the strict sense) differ from functions defined on objects through function expressions:
Example 1
const obj = {
method() {
super.test; // All good!
},
ordinaryFunction: function ordinaryFunction() {
super.test; // SyntaxError: 'super' keyword unexpected here
}
};
Example 2
const obj = {
method() {},
ordinaryFunction: function ordinaryFunction() {}
};
console.log( obj.ordinaryFunction.hasOwnProperty( 'prototype' ) ); // true
console.log( obj.method.hasOwnProperty( 'prototype' ) ); // false
new obj.ordinaryFunction(); // All good !
new obj.method(); // TypeError: obj.method is not a constructor
Example 3
const obj = {
method() {
console.log( method );
},
ordinaryFunction: function ordinaryFunction() {
console.log( ordinaryFunction );
}
};
obj.ordinaryFunction() // All good!
obj.method() // ReferenceError: method is not defined
A method is a property of an object whose value is a function. Methods are called on objects in the following format: object.method().
//this is an object named developer
const developer = {
name: 'Andrew',
sayHello: function () {
console.log('Hi there!');
},
favoriteLanguage: function (language) {
console.log(`My favorite programming language is ${language}`);
}
};
// favoriteLanguage: and sayHello: and name: all of them are proprieties in the object named developer
now lets say you needed to call favoriteLanguage propriety witch is a function inside the object..
you call it this way
developer.favoriteLanguage('JavaScript');
// My favorite programming language is JavaScript'
so what we name this: developer.favoriteLanguage('JavaScript');
its not a function its not an object? what it is? its a method
Your first line, is creating an object that references a function. You would reference it like this:
myFirstFunc(param);
But you can pass it to another function since it will return the function like so:
function mySecondFunction(func_param){}
mySecondFunction(myFirstFunc);
The second line just creates a function called myFirstFunc which would be referenced like this:
myFirstFunc(param);
And is limited in scope depending on where it is declared, if it is declared outside of any other function it belongs to the global scope. However you can declare a function inside another function. The scope of that function is then limited to the function its declared inside of.
function functionOne(){
function functionTwo(){}; //only accessed via the functionOne scope!
}
Your final examples are creating instances of functions that are then referenced though an object parameter. So this:
function myFirstFunc(param){};
obj.myFirst = myFirstFunc(); //not right!
obj.myFirst = new myFirstFunc(); //right!
obj.myFirst('something here'); //now calling the function
Says that you have an object that references an instance of a function. The key here is that if the function changes the reference you stored in obj.myFirst will not be changed.
While #kevin is basically right there is only functions in JS you can create functions that are much more like methods then functions, take this for example:
function player(){
this.stats = {
health: 0,
mana: 0,
get : function(){
return this;
},
set : function( stats ){
this.health = stats.health;
this.mana = stats.mana;
}
}
You could then call player.stats.get() and it would return to you the value of heath, and mana. So I would consider get and set in this instance to be methods of the player.stats object.
A function executes a list of statements example:
function add() {
var a = 2;
var b = 3;
var c = a + b;
return c;
}
1) A method is a function that is applied to an object example:
var message = "Hello world!";
var x = message.toUpperCase(); // .toUpperCase() is a built in function
2) Creating a method using an object constructor. Once the method belongs to the object you can apply it to that object. example:
function Person(first, last, age, eyecolor) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eyecolor;
this.name = function() {return this.firstName + " " + this.lastName;};
}
document.getElementById("demo").innerHTML = person.fullName(); // using the
method
Definition of a method: A method is a property of an object that is a function. Methods are defined the way normal functions are defined, except that they have to be assigned as the property of an object.
var myFirstFunc = function(param) {
//Do something
};
and
function myFirstFunc(param) {
//Do something
};
are (almost) identical. The second is (usually) just shorthand. However, as this jsfiddle (http://jsfiddle.net/cu2Sy/) shows, function myFirstFunc will cause the function to be defined as soon as the enclosing scope is entered, whereas myFirstFunc = function will only create it once execution reaches that line.
As for methods, they have a this argument, which is the current object, so:
var obj = {};
obj.func = function( ) {
// here, "this" is obj
this.test = 2;
}
console.log( obj.test ); // undefined
obj.func( );
console.log( obj.test ); // 2
The exact syntax you showed is because you can also do this:
function abc( ) {
this.test = 2;
}
var obj = {};
obj.func = abc;
obj.func( ); // sets obj.test to 2
but you shouldn't without good reason.
ecma document
4.3.31method :
function that is the value of a property
NOTE When a function is called as a method of an object, the object is
passed to the function as its this value.
It is very clear: when you call a function if it implicitly has a this (to point an object) and if you can't call the function without an object, the function deserves to name as method.
What's the difference between these two method of defining a 'class' in JavaScript?
Method One
Define method within the constructor:
function MyClass()
{
this.foo = function() { console.log('hello world!'); };
}
Method Two
Define method on the prototype:
function MyClass()
{}
MyClass.prototype.foo = function() { console.log('hello world!'); };
The first will create a new function object on each instantiation of your object, the second will assign a reference to a prototype method to each instance. In short: the second is more efficient, because all instances will share a single function object.
That's just the logic of a prototype chain, you can try and access anything via any object:
var objLiteral = {foo:'bar'};
When accessing objLiteral.foo JS will first look at the properties that the object itself has defined, and return the value if it is found. If JS can't find the property on the object itself, it'll check the object's prototype, hence:
objLiteral.valueOf();//method defined #Object.prototype
objLiteral.valueOf === Object.prototype.valueOf //true
But when you use your first method:
function SomeConstructor()
{
this.methd = function()
{
return true;
}
}
var f = new SomeConstructor();
var g = new SomeConstructor();
f.methd === g.methd;//FALSE!
That shows that we're dealing with 2 separate function objects. Move the function definition to the prototype and f.methd === g.methd; will be true:
function SomeConstructor()
{
}
SomeConstructor.prototype.methd = function()
{
return true;
}
var f = new SomeConstructor();
var g = new SomeConstructor();
f.methd === g.methd;//true!
In response to your comment:
Defining a method on a prototype-level allows you to change a method for a specific task, and then "reset" it back to it's default behaviour. Suppose you're in a function that's creating an AJAX request:
someObject.toString = function(){ return JSON.stringify(this);}
//when concatinating this object you'll get its json string
//do a lot of stuff
delete (someObject.toString);
Again JS will check if the object has the toString property defined on itself, which it has. So JS will delete the function you've assigned to the toString property. Next time the toString will be invoked, JS will start scanning the prototype chain all over again, and use the first occurance of the method (in the prototype). Let's clarify:
function SomeConstructor()
{
}
SomeConstructor.prototype.methd = function()
{
return true;
}
var f = new SomeConstructor();
var g = new SomeConstructor();
f.methd = function(){return false;};
g.methd();//returns true, still <-- method is gotten from the prototype
f.methd();//returns false <-- method is defined # instance level
delete (f.methd);
f.methd();//returns true, f doesn't have the method, but the prototype still does, so JS uses that.
Or even better, you can even replace an instance's method by a method from another prototype:
f.methd = Object.prototype.valueOf;//for as long as you need
the last example is pointless, because f has the valueOf method already: its inheritance chain looks like this: var f ---> SomeConstructor ---> Object, giving you access to all Object.prototype methods, too! Neat, isn't it?
These are just dummy examples, but I hope you see this is one of those features that make JS an incredibly flexible (sometimes too flexible, I must admit) and expressive language.
In first case the function will be created for each instance and set to the foo property in the object. In second case it is shared function. When you call obj.prop then it looks for it in object itself, if it is not there, then it looks for it in proto object and so on, it is called chain of prototypes.
For example this code provides foo:
function MyClass() {
this.foo = function () {};
}
var myVariable = new MyClass();
for (var i in myVariable) if (myVariable.hasOwnProperty(i)) console.log(i);
But this not:
function MyClass() {
}
MyClass.prototype.foo = function () {};
var myVariable = new MyClass();
for (var i in myVariable) if (myVariable.hasOwnProperty(i)) console.log(i);
I've recently started reading up on OOP javascript and one thing that authors seem to skip over is when an object A has been declared and suddenly I see "A.prototype.constructor =A;
For example,
var A = function(){}; // This is the constructor of "A"
A.prototype.constructor = A;
A.prototype.value = 1;
A.prototype.test = function() { alert(this.value); }
var a = new A(); // create an instance of A
alert(a.value); // => 1
So I run the command in firebug "var A = function(){};"
and then "A.Constructor" Which reveals it's a function. I understand this.
I run the code "A.prototype.constructor = A;" and I thought this changes the A constructor from Function to A.
The constructor property of A has been changed right? Instead when I run "A.constructor" it gives me function () still.
What's the point?
I also see A.constructor.prototype.constructor.prototype.. what is going on?
If A inherit B using A.prototype = new B();, you need to reset the constructor property for the class A using A.prototype.constructor=A;, otherwise instances of A would have a constructor of B.
In your case, A.prototype.constructor === A will return true, so A.prototype.constructor = A did nothing.
You can quickly test out that that additional assignment does absolutely nothing:
var A = function() {};
A.prototype.constructor === A; // true -- why assign then?
Resetting the constructor property only makes sense if you've assigned a new prototype object to the class, overwriting the original constructor:
var A = function() {};
A.prototype = protoObject; // some object with members that you'd like to inherit
A.prototype.constructor = A; // reset constructor
In your case, the author might be blindly doing this as good practice, even in cases where it's not necessary.
This code if often use in JS classic inheritance pattern (the code is from JavaScript Patterns by Stoyan Stefanov):
function inherit(C, P) {
var F = function () {};
F.prototype = P.prototype;
C.prototype = new F();
C.uber = P.prototype;
C.prototype.constructor = C;
}
to assign right constructor to the child class.
In your case it did nothing, since A.prototype.constructor === A before assignment.
You might want to see my answer to similar question:
https://stackoverflow.com/a/19616652/207661
TL;DR: constructor is not an own property of an instance. So to make things look consistent JavaScript interpreter needs to set prototype.constructor to function itself. This feature can be used in functions that operates generically on many different types of objects.
According to MDN, All objects inherit a constructor property from their prototype:
Example 1:
var o = {};
o.constructor === Object; // true
..
Example2:
function Tree() {
}
var theTree = new Tree();
console.log(theTree.constructor === Tree ); // true
At runtime, it does not make any difference based on the value of the constructor property.
However, as the constructor property returns a reference to the Object function that created the instance's prototype, one should reset the constructor property when they assign a new prototype to the Object function.
var Forest = function() {};
Forest.prototype = theTree;
console.log(new Forest().constructor === Tree ); // true
Forest.prototype.constructor = Forest;
console.log(new Forest().constructor === Forest ); // true
https://jsfiddle.net/j1ub9sap/
For details: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor