javascript : function and object...?
Solution 1:
You are looking for the constructor
concept.
All functions in JavaScript are objects and can be used to create objects:
function make_person(firstname, lastname, age) {
person = {};
person.firstname = firstname;
person.lastname = lastname;
person.age = age;
return person;
}
make_person("Joe", "Smith", 23);
// {firstname: "Joe", lastname: "Smith", age: 23}
However, in order to create new objects of a particular type (that is to say, that inherit a prototype, have a constructor, etc), a function can reference this
and if it is called with the new
operator then it will return an object with all of the attributes that are defined on this
in the function - this
in such cases references the new object we are creating.
function make_person_object(firstname, lastname, age) {
this.firstname = firstname;
this.lastname = lastname;
this.age = age;
// Note, we did not include a return statement
}
The key difference to note between make_person
and make_person_object
is that calling new make_person()
(as opposed to simply make_person()
) will not do anything different ... both will produce the same object. Calling make_person_object()
without the new
operator however, will define your this
attributes on the current this
object (generally window
if you are operating in the browser.)
Thus:
var Joe = make_person_object("Joe", "Smith", 23);
console.log(Joe); // undefined
console.log(window.firstname) // "Joe" (oops)
var John = new make_person_object("John", "Smith", 45);
console.log(John); // {firstname: "John", lastname: "Smith", age: 45}
Also, as @RobG points out, this way of doing things creates a reference to the prototype
property of make_person_object
on each "Person" we create. This enables us to add methods and attributes to persons after the fact:
// Assuming all that came before
make_person_object.prototype.full_name = "N/A";
make_person_object.prototype.greet = function(){
console.log("Hello! I'm", this.full_name, "Call me", this.firstname);
};
John.full_name // "N/A"
John.full_name = "John Smith";
make_person_object.full_name // Still "N/A"
John.greet(); // "Hello! I'm John Smith Call me John"
Convention has it that constructor functions like make_person_object
are capitalized, singularized and "nouned" (for lack of a better term) -- thus we would have a Person
constructor, rather than a make_person_object
which might be mistaken for an ordinary function.
See also:
-
The
new
operator - bobince's great introduction to subclassing in JavaScript (both with and without prototype inheritance.)
Solution 2:
Every function has a reference to this
. if you call Tip()
, this
will refer to the global object. If you call new Tip()
, a new object with a reference to Tip.prototype is created and this
will refer to that new object.
You can't use new
on objects, for instance new {}
throws TypeError: object is not a function
. If you are refering to new Object()
then that works since Object
is a function.
Solution 3:
Yes. In JavaScript, technically everything is an object. When you use new, it creates an instance of the Tip object and then calls the Tip function as if it were a constructor.
If you want to add functions to the Tip object, you should add them to Tip's prototype like so:
Tip.prototype.getContent = function() {
return this.content;
};
If you have that, and then you do:
var tip = new Tip("this is my content.");
alert(tip.getContent());
It'll show a message saying "this is my content."
You can only use new, however, if the object has a functional implementation. So this won't work:
var Tip = { content: txt, show: false };
var tipObj = new Tip();
Solution 4:
I have struggled to understand these concepts(functions as objects, prototype objects, __proto__ property, constructor property) for almost 8 years(2008-2016). First I started David Flanagan "JavaScript Definitive Guide 5/6th ed" for 4-5 years after multiple readings of Chapters 6,8,9; it did not make any sense to me but after struggling on Internet I some what able to manage functions(typical C++ function with properties) as objects; because object can also have methods. And luckily in 7th year 2015, I started Wrox Nicholas C. Zakas "Professional JavaScript for Web Developers 3rd ed" Chapter 6,7; and it was really very helpful to understand above four concepts. Traditionally in C/C++/C# functions are thought of as to modify an object; or in other words they are made for the "doing something" where as Objects are made for maintaining state of global running context with methods to change its own object state. So if functions can be first class objects then why objects can not be like functions ?
The main key question here should be WHY ? Why not single conceptual entity like "associative-function" or "chained-arguments" ? And here is my understanding: Browser exe is a single threaded application and this exe controls calling JS interpreter with predefined scope chain(some what similar to a string of commands with arguments); now at runtime the JS engine(not interpreter) loads the code in hoisting fashion(since there is no main method so uplifting the well defined keyworded codes and its call). In this hoisted code if functions are not treated as objects then they have to be maintained on separate call context(out of scope chain) which is easily possible in c/c++/c#(bcoz of multi thread and unlimited memory) but not in JS. Hence "to-do smth on chained object" makes a java script function as first class object. In fact JS objects also do the same thing; the only difference is "calling an object" is not there in objects where as "calling a function" is chained context which make sense. Functions can also be thought of as "bunch of variables with assembly language instructions with address link(chain)". The linking part is another side of story as top->bottom linking(prototype object) vs bottom->top linking(__proto__ property) vs object blue print->object instances(constructor property). Few months back I found the following image as helpful for understanding linking.
http://judis.me/wordpress/wp-content/uploads/2015/08/JavaScriptDiagram.png "JS Object model"