Why in JavaScript is a function considered both a constructor and an object? - Stack Overflow
Constructor concept in JavaScript - Stack Overflow
Object Constructor function with .prototype method in JavaScript
[AskJS] Factory functions vs. Constructors. Why choose factory functions?
Videos
There is nothing magical about functions and constructors. All objects in JavaScript are … well, objects. But some objects are more special than the others: namely built-in objects. The difference lies mostly in following aspects:
- General treatment of objects. Examples:
- Numbers and Strings are immutable (⇒ constants). No methods are defined to change them internally — new objects are always produced as the result. While they have some innate methods, you cannot change them, or add new methods. Any attempts to do so will be ignored.
nullandundefinedare special objects. Any attempt to use a method on these objects or define new methods causes an exception.
- Applicable operators. JavaScript doesn't allow to (re)define operators, so we stuck with what's available.
- Numbers have a special way with arithmetic operators:
+,-,*,/. - Strings have a special way to handle the concatenation operator:
+. - Functions have a special way to handle the "call" operator:
(), and thenewoperator. The latter has the innate knowledge on how to use theprototypeproperty of the constructor, construct an object with proper internal links to the prototype, and call the constructor function on it setting upthiscorrectly.
- Numbers have a special way with arithmetic operators:
If you look into the ECMAScript standard (PDF) you will see that all these "extra" functionality is defined as methods and properties, but many of them are not available to programmers directly. Some of them will be exposed in the new revision of the standard ES3.1 (draft as of 15 Dec 2008: PDF). One property (__proto__) is already exposed in Firefox.
Now we can answer your question directly. Yes, a function object has properties, and we can add/remove them at will:
var fun = function(){/* ... */};
fun.foo = 2;
console.log(fun.foo); // 2
fun.bar = "Ha!";
console.log(fun.bar); // Ha!
It really doesn't matter what the function actually does — it never comes to play because we don't call it! Now let's define it:
fun = function(){ this.life = 42; };
By itself it is not a constructor, it is a function that operates on its context. And we can easily provide it:
var context = {ford: "perfect"};
// now let's call our function on our context
fun.call(context);
// it didn't create new object, it modified the context:
console.log(context.ford); // perfect
console.log(context.life); // 42
console.log(context instanceof fun); // false
As you can see it added one more property to the already existing object.
In order to use our function as a constructor we have to use the new operator:
var baz = new fun();
// new empty object was created, and fun() was executed on it:
console.log(baz.life); // 42
console.log(baz instanceof fun); // true
As you can see new made our function a constructor. Following actions were done by new:
- New empty object (
{}) was created. - Its internal prototype property was set to
fun.prototype. In our case it will be an empty object ({}) because we didn't modify it in any way. fun()was called with this new object as a context.
It is up to our function to modify the new object. Commonly it sets up properties of the object, but it can do whatever it likes.
Fun trivia:
Because the constructor is just an object we can calculate it:
var A = function(val){ this.a = val; }; var B = function(val){ this.b = val; }; var C = function(flag){ return flag ? A : B; }; // now let's create an object: var x = new (C(true))(42); // what kind of object is that? console.log(x instanceof C); // false console.log(x instanceof B); // false console.log(x instanceof A); // true // it is of A // let's inspect it console.log(x.a); // 42 console.log(x.b); // undefined // now let's create another object: var y = new (C(false))(33); // what kind of object is that? console.log(y instanceof C); // false console.log(y instanceof B); // true console.log(y instanceof A); // false // it is of B // let's inspect it console.log(y.a); // undefined console.log(y.b); // 33 // cool, heh?Constructor can return a value overriding the newly created object:
var A = function(flag){ if(flag){ // let's return something completely different return {ford: "perfect"}; } // let's modify the object this.life = 42; }; // now let's create two objects: var x = new A(false); var y = new A(true); // let's inspect x console.log(x instanceof A); // true console.log(x.ford); // undefined console.log(x.life); // 42 // let's inspect y console.log(y instanceof A); // false console.log(y.ford); // perfect console.log(y.life); // undefinedAs you can see
xis ofAwith the prototype and all, whileyis our "naked" object we returned from the constructor.
Your understanding is wrong:
myFunction().myProperty; // myFunction has no properties
The reason it does not work is because ".myProperty" is applied to the returned value of "myFunction()", not to the object "myFunction". To wit:
$ js
js> function a() { this.b=1;return {b: 2};}
js> a().b
2
js>
Remember, "()" is an operator. "myFunction" is not the same as "myFunction()". You don't need a "return" when instanciang with new:
js> function a() { this.b=1;}
js> d = new a();
[object Object]
js> d.b;
1
First of all the person is a regular JavaScript function. When you call it, of course, lines:
this.firstName = "";
this.lastName = "";
are executed. Constructor function is rather a concept than a something really existing in the JS language. You need constructors to create new similar objects by calling new MyCtr(). At the same time you need regular functions to encapsulate piece of logic and make it reusable in different places without copy/paste the code.
You can use all functions in JavaScript as a constructor. Just add new keyword in front of function call expression. This thing changes the context of execution of the function. Without new the function is executed against global object (window in a browser). And this variable inside the function refers to the context.
Not every function is ready to be a constructor. Usually, constructor functions are doing something with this variable which is a reference to an object which is created during new MyCtr() call. Also, constructor functions never return a value.
Lets look at few examples (you can execute it directly in the browser's console):
function foo() {
this.a = 1;
}
foo(); // using function as a regular function. Ctx is window.
console.log(window.a); // prints "1"
foo.call(window); // explicitly specify execution ctx. The same as just foo() call
var instance = new foo(); // using foo as a constructor
console.log(instance.a); // prints "1"
// actually you can do it without new keyword
var instance = {}; // manually create new object
foo.call(instance); // manually call foo against this object
console.log(instance.a); // prints "1"
// However, the code above is not strictly equivalent to the code using new.
// It omits the concept of prototype, but it's enough for our current task.
Regarding functions and files. There is no such thing in the language like in the Java that each class must be placed in the separate file. You can put all your functions within one file and then use it as constructors or not. However, the best practice is to reside one constructor function (read as class) per one file (called module).
any function in JavaScript can act as a constructor when the function is invoked with new operator.
Now, what a constructor does ? it creates/instantiate an object from the constructor function. like its shown in the below image.
LINK , it explain the fundamentals very clearly.
what is this ?
when this constructor function is invoked with new, this points to the new object created at that invocation. and in that object we set firtName and lastName (it is the initialization of the new object created).
Now when we add methods to the prototype of the constructor , that is being shared between all the objects created using the constructor function(picture explains it lit bit more)
and regarding your last query "And also in one of the blogs I was studying if the file name is Samplescript.js and if a function is written using the same name inside this like var Samplescript=function(){}, will this function be considered a constructor? Please clarify me this"
any function in JavaScript can act as a constructor when the function is invoked with new operator, and its not the way that blog says.
so please stop reading that blog, the link i provided is a very good starting point