I have been working with JS for a few months now and I stumbled upon this interesting (at least to me) thing.
Take a look at this code:
class myClass
{
constructor()
{
this.x = 0;
}
}
function myFunc(){}
myClass.myFunc = myFunc;
I can call myClass.myFunc(), but myClass is just a function. In fact, I could rewrite it as
function myClass()
{
this.x = 0;
}
and it would behave the same and I would still be able to call myClass.myFunc(). So what actually is a function (like, "under the hood")? It seems to behave more like an object that can be called if it makes any sense, thus being able to have fields of its own.
Also, is this considered bad practice?
In node I have
module.exports = myClass;
module.exports.myFunc = myFunc;
Is this okay to do? Or is this frowned upon? What are the cons, if any?
EDIT: I'm not asking how to have a static method, I'm asking why this happens.
In JavaScript a function is an actual value. Values a categorized by data type (a data type describes a possible set of values). JavaScript has the following data types:
Boolean
Number
String
Undefined
Null
Symbol
Object
A function is obviously neither of the first 6, it is indeed an Object. And as such it can have arbitrary properties, just like any other object.
What makes a function object special?
Per specification objects have "internal methods". You can think of them as being just like normal properties except that they cannot be accessed in user code. Only the JavaScript engine can access them.
Function objects have an internal method called [[Call]] and an internal slot called [[ECMAScriptCode]]. The latter contains a parsed representation of the function body and is evaluated when [[Call]] is invoked (which happens in a call expression (foo())).
Specifically for classes, or rather the functions created through class syntax, there is also the internal [[Construct]] method. It works very similar to [[Call]] but is used when a function is invoked via the new keyword.
See also
What is the main core difference between a javascript function and javascript object?
If functions are objects, where does the function's body go? (referring to an earlier version of the spec)
Why the property "prototype" is absent in definition methods of ES6 classes
You can use static method:
class myClass
{
constructor()
{
this.x = 0;
}
static myFunc(){
return 'Hello';
}
}
module.exports = myClass
or simply export a new instance of myClass:
class myClass
{
constructor()
{
this.x = 0;
}
myFunc(){
return 'Hello';
}
}
module.exports = new myClass
In both approach you can treat myFunc as a static function:
const myclass = require('myClass');
myClass.myFunc();
// will print out 'Hello'
Related
Currently reading js.info and came upon this:
"Let’s note once again – technically, any function (except arrow functions, as they don’t have this) can be used as a constructor. It can be run with new, and it will execute the algorithm above. The “capital letter first” is a common agreement, to make it clear that a function is to be run with new."
This is the function they included but it doesn't seem to portray what they described. I also couldn't get it to run at all (several errors).
// create a function and immediately call it with new
let user = new function() {
this.name = "John";
this.isAdmin = false;
// ...other code for user creation
// maybe complex logic and statements
// local variables etc
};
I'm curious what this would look like in practice and what use cases exist for a constructor function that does not return/pertain to an object?
As for use cases: constructor functions are de facto object factories. It might be that you want to hide complicated/non-standard construction details from client code while maintaining a familiar construction API using new. The ability to return any object you like from a constructor function invoked with new enables this.
More info
Let's rearrange your code to make it a little easier to follow (this is only marginally different in that the constructor function now will have an inferred name 'F'):
let F = function() {
this.name = "John";
this.isAdmin = false;
// ...other code for user creation
// maybe complex logic and statements
// local variables etc
};
let user = new F; // or `new F();` if you prefer, parens are optional
console.log(Object.getPrototypeOf(user) === F.prototype) // true
When F is invoked with new:
A new object o is immediately created, with its [[Prototype]] set to refer to the .prototype property of function F.
The this value inside F is set to be o for the duration of the invocation of F as a constructor function.
The .constructor property of o is set to point to F
The return value of F is automatically set to be o if no value is explicitly returned.
Most constructor functions do not explicitly return an object. This is because invocation with new implicitly creates a new object, o, configured according to the rules of prototypical inheritance; o is set to be the this value used for the duration of the execution of the constructor function, and o is automatically and implicitly returned if no value is explicitly returned.
That said, programmers can instead explicitly return any object they like from a constructor function, and this overrides and prevents the implicit return.
Any function that implements the [[Construct]] internal method can be used as a constructor function with new (and super).
Ordinary function declarations (function foo() { ... }) and class constructors (class foo { constructor() {} }) can be used as constructor functions. Fat arrow functions, object literal methods, async functions and class methods cannot be used as constructor functions because they don't have the [[Construct]] internal method.
I am trying to understand how "classes" work in ES5 and how I can apply my knowledge of traditional, typed object oriented languages like Java to javascript.
In the following code sample I have commented with my questions.
var MyClass = (function () {
// [What am I?] A private variable?
var myVariable1
// Constructor.
function MyClass() {
// Essentially a public variable.
this.myVariable2 = 0;
}
// Public method returning myVariable1.
MyClass.prototype.myMethod1 = function () {
return myVariable1;
};
// Public method returning public variable.
MyClass.prototype.myMethod2 = function () {
return this.myVariable2;
};
// [What am I?] A private method?
function myMethod3 () {
return 0;
}
return MyClass;
}());
I am mostly wondering about the "private" stuff. Like, what happens if I have multiple instances of this class? Can they interfere with each others private variables and functions?
First I'll address this bit:
...and how I can apply my knowledge of traditional, typed object oriented languages like Java to javascript.
You can frequently get away with thinking of JavaScript as being a bit like Java/C#/etc., but if you do:
It'll bite you at some point, because JavaScript is not like Java/C#/etc., it is fundamentally different even though it has some trappings that make it look similar;
and
You'll miss out on the true power of JavaScript by not knowing how to use its fundamentally-different nature.
How do I know? I did exactly that, came from a Java (and even C++) background and assumed JavaScript was similar, and got bitten, and missed out (initially). :-)
That's not remotely meant as any form of criticism, it's just a word to the wise. Try to learn in depth how JavaScript prototypical inheritance and closures work, and you'll find that the way you solve problems will be slightly different than the way you would in Java/C#/etc.
In Old Environments
Answers to your direct queries inline in this code block, but in 2022 I added a bit below ("In Modern Environments") to address the new modern features recently added to JavaScript to directly address these use cases in different ways.
var MyClass = (function () {
// [What am I?] A private variable?
// ==> A private *class* variable (static variable). Not instance-specific.
var myVariable1
// Constructor.
function MyClass() {
// Essentially a public variable.
// ==> A public field/property/variable, choose your terminology. :-)
// ==> The Java spec calls them both fields and variables (oddly).
// ==> In JavaScript, they're called properties.
this.myVariable2 = 0;
}
// Public method returning myVariable1.
// ==> Correct, but note that myVariable1 is shared across all instances
MyClass.prototype.myMethod1 = function () {
return myVariable1;
};
// Public method returning public variable.
// ==> Yes, note that this one is returning an instance-specific field/property/variable
MyClass.prototype.myMethod2 = function () {
return this.myVariable2;
};
// [What am I?] A private method?
// ==> A private *class* method (static method), yes.
function myMethod3 () {
return 0;
}
return MyClass;
}());
I am mostly wondering about the "private" stuff. Like, what happens if I have multiple instances of this class? Can they interfere with each others private variables and functions?
Yes, as I mentioned in the comments, they're class-wide. If you wanted to have a private "instance field", you'd have to declare it within your constructor, and create any functions that needed to have access to it within the constructor so that they closed over it:
function MyClass(arg) {
var privateInstanceInfo = arg; // We could also just use arg directly
this.accessThePrivateInstanceInfo = function() {
return privateInstanceInfo * 42;
};
}
MyClass.prototype.useOnlyPublicInfo = function() {
// This cannot access `privateInstanceInfo` directly.
// It *can* access the function `accessThePrivateInstanceInfo`
// because that's public:
return accessThePrivateInstanceInfo();
};
var c = new MyClass(2);
console.log(c.useOnlyPublicInfo()); // 84
This is all down to a concept called closures, which is outlined in detail in this question and its answers: How do JavaScript closures work? I'll also reference my article from several years ago Closures are not complicated, which while it uses some older terms for things compared to the latest specification, still describes the concepts just fine.
The inline-invoked function (IIFE) you've used as a wrapper creates a single execution context that all of the functions within it close over. That means they have live access to the variables and functions defined within that context, even after the function returns. Since you only call it once, there's only one context, and so only one myVariable1 and myMethod3.
In my example creating private instance information, we use the fact that a new context is created for each call to the constructor. That context isn't shared with anything else, and so becomes instance-specific.
There's a way to get near-private instance properties without having to define functions in the constructor, which is to use a randomly-selected name:
function makeRandomName() {
var str = "";
while (str.length < 10) {
str += String.fromCharCode(32 + Math.floor(95 * Math.random()));
}
return "__" + str;
}
var MyClass = (function() {
var pseudoPrivatePropName = makeRandomName();
function MyClass() {
this[pseudoPrivatePropName] = 42;
}
// ....
return MyClass;
})();
The code inside the IIFE knows the name of the property, the code outside of it doesn't. Now, malicious code could still find the property, but it's become much more challenging, particularly if you have more than one. (And if you have more than one, you need a better name allocator than the one above.) (Details in this very-outdated article in my blog.)
In ES2015 (ES6) you could use
var pseudoPrivatePropName = Symbol();
...instead of having a name allocator, but it doesn't make the property any more private.
In Modern Environments
In modern environments though, you can use new features that have been added to JavaScript for the ES2022 specification:
Class Public Instance Fields & Private Instance Fields
Private instance methods and accessors
Static class fields and private static methods
Here's how you might right MyClass using those features and ES2015's class syntax:
class MyClass {
// Static class field (class-wide, not instance-specific)
static myVariable1;
// Instance class field (property) (instance-specific)
myVariable2 = 0;
// Private class field (instance-specific)
#privateInstanceInfo;
// Private static class field (class-wide, not instance-specific)
static #privateStaticInfo;
// Constructor for the class
constructor(arg) {
this.#privateInstanceInfo = arg;
}
// Public instance method returning static member
myMethod1() {
// Note that `MyClass.myVariable1` is shared across all instances
return MyClass.myVariable1;
}
// Public instance method return instance field (property) value
myMethod2() {
return this.myVariable2;
}
// Public instance method accessing the private field; all methods declared
// for the class can access it, not just this one
accessThePrivateInstanceInfo() {
return this.#privateInstanceInfo * 42;
}
// Private instance method
#myMethod3() {
return 0;
}
// Static method
static myStaticMethod() {
return this.#getPrivateStaticInfo(); // Or `MyClass.#getPrivateStaticInfo();`
}
// Private static method
static #getPrivateStaticInfo() {
return this.#privateStaticInfo; // Or `MyClass.#privateStaticInfo`
}
}
On those last two, the static method and the private static method, note that usually this during the call will refer to the class constructor itself (MyClass), because usually you're calling static members by doing MyClass.myStaticMethod(). But as usual with this, that's not necessarily true; if you did const f = MyClass.myStaticMethod; f();, this during the call wouldn't refer to MyClass. Using this in static methods to refer to the constructor is friendly to subclasses (because a subclass constructor's prototype is its superclass constructor; details here), but does mean you have to deal with the usual caveats around this.
Use # for private, and _ for protected.
I was wondering - what's the difference between JavaScript objects, classes and functions?
Am I right in thinking that classes and functions are types of objects?
And what distinguishes a class from a function? Or are they really the same thing, just the term for them changes according to how they are used?
function func() { alert('foo'); } // a function
func(); // call the function - alerts 'foo'
var func2 = function () { alert('hello'); } // acts the same way as 'func' surely?
func2(); // alerts 'hello'
var Class = function() { alert('bar'); }; // a class
var c = new Class(); // an istance of a class - alerts 'bar'
Sure, classes have methods and properties and can be instantiated - but then, I could do the same with any old function - or not?
As you must already be aware by now there are no classes in JavaScript. Instead functions in JavaScript may be made to behave like constructors by preceding a function call with the new keyword. This is known as the constructor pattern.
In JavaScript, everything is an object except for the primitive data types (boolean, number, and string), and undefined. On the other hand null is actually an object reference even though you may at first believe otherwise. This is the reason typeof null returns "object".
Functions in JavaScript are similar to functables in Lua (i.e. they are callable objects). Hence a function can be used in place of an object. Similarly, arrays are also objects in JavaScript. On the other hand, objects can be thought of as associative arrays.
The most important point however is that there are no classes in JavaScript because JavaScript is a prototypal object-oriented language. This means that objects in JavaScript directly inherit from other objects. Hence we don't need classes. All we need is a way to create and extend objects.
Read the following thread to learn more about prototypal inheritance in JavaScript: Benefits of prototypal inheritance over classical?
Update 2015
There are classes in JavaScript they just aren't used on older browsers:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
It has constructors, extensions, and the like.
class Cat {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Lion extends Cat {
speak() {
super.speak();
console.log(this.name + ' roars.');
}
}
A Class in JS:
function Animal(){
// Private property
var alive=true;
// Private method
function fight(){ //... }
// Public method which can access private variables
this.isAlive = function() { return alive; }
// Public property
this.name = "Joe";
}
// Public method
Animal.prototype.play = function() { alert("Bow wow!"); }
// .. and so on
Now when you create it's object
var obj = new Animal();
You can expect anything of this object as you would from objects in other language. Just the efforts to achieve it, was a bit different. You should also be looking at inheritance in JS.
Getting back too your question, I'll reword it as:
//Class : A representation of a set with common properties.
//object : One from the set with the same properties.
var Class = function() {alert('bar');}; // A set of function which alert 'bar'
var object = new Class(); // One of the functions who alert's 'bar'.
JavaScript does not have classes, and functions are actually objects in JavaScript (first-class citizens).
The only difference that function objects have is that they are callable.
function func() { alert('foo'); } // a function - Correct
func(); // call the function - alerts 'foo' - Correct
var func2 = function () { alert('foo'); } // same as 'func' surely? - Nope, func2 is a different object, that apparently does the same thing when called.
var Class = function() { alert('bar'); }; - It's a function with no name stored in variable Class.
var c = new Class(); - Calls function stored in Class supplying new empty object as this and returning that object. Functions called as new functionA() are expected to work as constructors and prepare a newly created object (this). In your case - constructor does nothing with the object and just alerts bar.
You also get classes in ES6 that look like this:
//class
class Cat {
//constructor
constructor() {
this.name = 'Snowball';
}
//method
meow() {
console.log('Hello, nyah! My name is ' + this.name + ' nyah!~');
}
};
There are no classes in javascript. But, there are ways to make a function to behave like a class in other languages.
A very good explanation is given here 3 way to define a class in js
Also, found a very good reference for OOP in Javascript
Object is the base type in JavaScript i.e. all the user defined data types inherits from Object in one way or another. So if you define a function or a class [note as of now JS doesn't support class construct, but its proposed in ECMAScript version 6], it will implicitly inherit from Object type.
Classes are really used for encapsulating logical functions and properties into one type / entity and you can 'new' it up using constructor syntax. So if you define a 'Customer' class, you can instantiate it multiple times and each instance / object can have different values. They can even share the values if you define class level value using prototype.
Since JS doesn't support class construct at the moment, functions can really act as individual method as well as container for other functions or types.
I hope with ECMAScript 6 we will have clear separation between these constructs similar to what we have in other languages like C#, Java etc.
In JavaScript what is the difference between these two examples:
Prerequisite:
function SomeBaseClass(){
}
SomeBaseClass.prototype = {
doThis : function(){
},
doThat : function(){
}
}
Inheritance example A using Object.create:
function MyClass(){
}
MyClass.prototype = Object.create(SomeBaseClass.prototype);
Inheritance example B using the new keyword
function MyClass(){
}
MyClass.prototype = new SomeBaseClass();
Both examples seem to do the same thing. When would you chose one over the other?
An additional question:
Consider code in below link (line 15), where a reference to the the function's own constructor is stored in the prototype. Why is this useful?
https://github.com/mrdoob/three.js/blob/master/src/loaders/ImageLoader.js
Excerpt (if you don't want to open the link):
THREE.ImageLoader.prototype = {
constructor: THREE.ImageLoader
}
In your question you have mentioned that Both examples seem to do the same thing, It's not true at all, because
Your first example
function SomeBaseClass(){...}
SomeBaseClass.prototype = {
doThis : function(){...},
doThat : function(){...}
}
function MyClass(){...}
MyClass.prototype = Object.create(SomeBaseClass.prototype);
In this example, you are just inheriting SomeBaseClass' prototype but what if you have a property in your SomeBaseClass like
function SomeBaseClass(){
this.publicProperty='SomeValue';
}
and if you use it like
var obj=new MyClass();
console.log(obj.publicProperty); // undefined
console.log(obj);
The obj object won't have publicProperty property like in this example.
Your second example
MyClass.prototype = new SomeBaseClass();
It's executing the constructor function, making an instance of SomeBaseClass and inheriting the whole SomeBaseClass object. So, if you use
var obj=new MyClass();
console.log(obj.publicProperty); // SomeValue
console.log(obj);
In this case its publicProperty property is also available to the obj object like in this example.
Since the Object.create is not available in some old browsers, in that case you can use
if(!Object.create)
{
Object.create=function(o){
function F(){}
F.prototype=o;
return new F();
}
}
Above code just adds Object.create function if it's not available so you can use Object.create function and I think the code above describes what Object.create actually does. Hope it'll help in some way.
Both examples seem to do the same thing.
That's true in your case.
When would you chose one over the other?
When SomeBaseClass has a function body, this would get executed with the new keyword. This usually is not intended - you only want to set up the prototype chain. In some cases it even could cause serious issues because you actually instantiate an object, whose private-scoped variables are shared by all MyClass instances as they inherit the same privileged methods. Other side effects are imaginable.
So, you should generally prefer Object.create. Yet, it is not supported in some legacy browsers; which is the reason you see the new-approach much too frequent as it often does no (obvious) harm. Also have a look at this answer.
The difference becomes obvious if you use Object.create() as it is intended. Actually, it does entirely hideout the prototype word from your code, it'll do the job under the hood. Using Object.create(), we can go like
var base = {
doThis : function(){
},
doThat : function(){
}
};
And then we can extend/inherit other objects from this
var myObject = Object.create( base );
// myObject will now link to "base" via the prototype chain internally
So this is another concept, a more "object oriented" way of inherting. There is no "constructor function" out of the box using Object.create() for instance. But of course you could just create and call a self defined constructor function within those objects.
One argument for using Object.create() is that it might look more natural to mix/*inherit* from other objects, than using Javascripts default way.
I am not an expert in java script but here is a simple example to understand difference between "Object.create" and "new" ..
step 1 : create the parent function with some properties and actions..
function Person() {
this.name = 'venkat';
this.address = 'dallas';
this.mobile='xxxxxxxxxx'
}
Person.prototype.func1 = function () {
return this.name + this.address;
}
step 2 : create a child function (PersonSalary) which extends above Person function using New keyword..
function PersonSalary() {
Person.call(this);
}
PersonSalary.prototype = new Person();
PersonSalary();
step 3 : create second child function (PersonLeaves) which extends above Person function using Object.create keyword..
function PersonLeaves() {
Person.call(this);
}
PersonLeaves.prototype = Object.create(Person.prototype);
PersonLeaves();
// Now check both child functions prototypes.
PersonSalary.prototype
PersonLeaves.prototype
both of these child functions will link to Person(parent function) prototype and can access it's methods but if you create child function using new it will return a brand new object with all parent properties which we don't need and also when you create any object or function using "New" that parent function is executed which we don't want to be.
Here are the takeaways
if you just want to delegate to some methods in parent function and don't want a new object to be created , using Object.create is best way.
A couple of additions to this answer set, mindful that JS obviously now has native classes:
In both Example A and Example B the static inheritance chain is not configured.
In Example B the superclass constructor is run at the "wrong time". It is run before the call to instantiate an instance of the subclass, before any arguments are known and perhaps before you have decided to instantiate an instance of the subclass. Note that constructors can contain any logic they like, including side-effectful logic, so this can be impactful.
Post-ES6 the inheritance chain can be configured in a standardised way using the class and extends keywords (which solve both of these issues).
See also.
I am just learning Javascript and I was wondering, is using the prototype declaration, like this:
function TSomeObj()
{
this.name="my object";
}
TSomeObj.prototype.showname = function() {
alert(this.name);
}
Basically the same as doing it like this:
function TSomeObj()
{
this.name="my object";
this.showname = function() {
alert(this.name);
}
}
When I dump the object's properties I get the same result:
TSomeObj (inline version) =
{
'name': 'my object',
'test': function
}
TSomeObj (prototype declaration) =
{
'name': 'my object',
'test': function
}
What exactly is the benefit of using prototype declarations? Except less cluttering and more orderly sourcecode perhaps.
Update: I should perhaps have made it more clear that it was the final result i was curious about. The end result is ofcourse the same (i.e both register a new function in the object prototype) - but the way they do it is wildly different. Thank you for all replies and info!
Note: This answer is accurate but does not fully reflect the new way to create classes in JavaScript using the ES6 class Thing {} syntax. Everything here does in fact apply to ES6 classes, but might take some translation.
I initially answered the wrong question. Here is the answer to your actually-asked question. I'll leave my other notes in just in case they're helpful to someone.
Adding properties to an object in the constructor function through this.prop is different from doing so outside through Object.prototype.prop.
The most important difference is that when you add a property to the prototype of a function and instantiate a new object from it, that property is accessed in the new object by stepping up the inheritance chain rather than it being directly on the object.
var baseobj = {};
function ObjType1() {
this.prop = 2;
}
function ObjType2() {}
ObjType1.prototype = baseobj;
ObjType2.prototype = baseobj; // these now have the *same* prototype object.
ObjType1.prototype.prop = 1;
// identical to `baseobj.prop = 1` -- we're modifying the prototype
var a = new ObjType1(),
b = new ObjType2();
//a.hasOwnProperty('prop') : true
//b.hasOwnProperty('prop') : false -- it has no local property "prop"
//a: { prop = 2 }, b : { prop = 1 } -- b's "prop" comes from the inheritance chain
baseobj.prop = 3;
//b's value changed because we changed the prototype
//a: { prop = 2 }, b : { prop = 3 }
delete a.prop;
//a is now reflecting the prototype's "prop" instead of its own:
//a: { prop = 3 }, b : { prop = 3 }
A second difference is that adding properties to a prototype occurs once when that code executes, but adding properties to the object inside the constructor occurs each time a new object is created. This means using the prototype performs better and uses less memory, because no new storage is required until you set that same property on the leaf/proximate object.
Another difference is that internally-added functions have access to private variables and functions (those declared in the constructor with var, const, or let), and prototype-based or externally-added functions do not, simply because they have the wrong scope:
function Obj(initialx, initialy) {
var x = initialx,
y = initialy;
this.getX = function() {
return x;
}
var twoX = function() { // mostly identical to `function twoX() { ... }`
return x * 2;
}
this.getTwoX = function() {
return twoX();
}
}
Obj.prototype.getY = function() {
return y; // fails, even if you try `this.y`
}
Obj.prototype.twoY = function() {
return y * 2; // fails
}
Obj.prototype.getTwoY = function() {
return twoY(); // fails
}
var obj = new Obj();
// obj.y : fails, you can't access "y", it is internal
// obj.twoX() : fails, you can't access "twoX", it is internal
// obj.getTwoX() : works, it is "public" but has access to the twoX function
General notes about JavaScript objects, functions, and inheritance
All non-string and non-scalar variables in JavaScript are objects. (And some primitive types undergo boxing when a method is used on them such as true.toString() or 1.2.valueOf()). They all act somewhat like a hash/dictionary in that they have an unlimited(?) number of key/value pairs that can be assigned to them. The current list of primitives in JavaScript is: string, number, bigint, boolean, undefined, symbol, null.
Each object has an inheritance chain of "prototypes" that go all the way up to the base object. When you access a property of an object, if that property doesn't exist on the object itself, then the secret prototype of that object is checked, and if not present then that object's prototype, so on and so forth all the way up. Some browsers expose this prototype through the property __proto__. The more modern way to get the prototype of an object is Object.getPrototypeOf(obj). Regular objects don't have a prototype property because this property is for functions, to store the object that will be the prototype of any new objects created using that function as their constructor.
A JavaScript function is a special case of an object, that in addition to having the key/value pairs of an object also has parameters and a series of statements that are executed in order.
Every time a function object is invoked it is paired with another object that is accessed from within the function by the keyword this. Usually, the this object is the one that the function is a property of. For example, ''.replace() boxes the string literal to a String, then inside the replace function, this refers to that object. another example is when a function is attached to a DOM element (perhaps an onclick function on a button), then this refers to the DOM element. You can manually choose the paired this object dynamically using apply or call.
When a JavaScript function is invoked with the new keyword as in var obj = new Obj(), this causes a special thing to happen. If you don't specifically return anything, then instead of obj now containing the return value of the Obj function, it contains the this object that was paired with the function at invocation time, which will be a new empty object with the first parent in its inheritance chain set to Obj.prototype. The invoked Obj() function, while running, can modify the properties of the new object. Then that object is returned.
You don't have to worry much about the keyword constructor, just suffice it to say that obj.constructor points to the Obj function (so you can find the thing that created it), but you'll probably not need to use this for most things.
Back to your question. To understand the difference between modifying the properties of an object from within the constructor and modifying its prototype, try this:
var baseobj = {prop1: 'x'};
function TSomeObj() {
this.prop2 = 'y';
};
TSomeObj.prototype = baseobj;
var a = new TSomeObj();
//now dump the properties of `a`
a.prop1 = 'z';
baseobj.prop1 = 'w';
baseobj.prop2 = 'q';
//dump properties of `a` again
delete a.prop1;
//dump properties of `a` again
You'll see that setting a.prop1 is actually creating a new property of the proximate object, but it doesn't overwrite the base object's prop1. When you remove prop1 from a then you get the inherited prop1 that we changed. Also, even though we added prop2 after a was created, a still has that property. This is because javascript uses prototype inheritance rather than classic inheritance. When you modify the prototype of TSomeObj you also modify all its previously-instantiated objects because they are actively inheriting from it.
When you instantiate a class in any programing language, the new object takes on the properties of its "constructor" class (which we usually think of as synonymous with the object). And in most programming languages, you can't change the properties or methods of the class or the instantiated object, except by stopping your program and changing the class declaration.
Javascript, though, lets you modify the properties of objects and "classes" at run-time, and all instantiated objects of that type class are also modified unless they have their own properties that override the modification. Objects can beget objects which can beget objects, so this works in a chain all the way up to the base Object class. I put "classes" in quotes because there really isn't such a thing as a class in JavaScript (even in ES6, it's mostly syntactic sugar), except that the new keyword lets you make new objects with the inheritance chain hooked up for you, so we call them classes even though they're just the result of constructor functions being called with the new keyword.
Some other notes: functions have a Function constructor, objects have an Object constructor. The prototype of the Function constructor is (surprise, surprise) Object.
Inheriting from an object without the constructor function running
In some cases, it's useful to be able to create a new "instance of an object" without the constructor function running. You can inherit from a class without running the class's constructor function like so (almost like manually doing child.__proto__ = parent):
function inheritFrom(Class) {
function F() {};
F.prototype = Class.prototype;
return new F();
}
A better way to do this now is Object.setPrototypeOf().
The accepted answer missed the most important distinctions between prototypes and methods bound to a specific object, so I'm going to clarify
Prototype'd functions are only ever declared once. Functions attached using
this.method = function(){}
are redeclared again and again whenever you create an instance of the class. Prototypes are, thus, generally the preferred way to attach functions to a class since they use less memory since every instance of that class uses the same functions. As Erik pointed out, however, functions attached using prototypes vs attached to a specific object have a different scope, so prototypes don't have access to "private" variables defined in a function constructor.
As for what a prototype actually is, since it's an odd concept coming from traditional OO languages:
Whenever you create a new instance of a function:
var obj = new Foo();
the following logic is run (not literally this code, but something similar):
var inheritsFrom = Foo,
objectInstance = {};
objectInstance.__proto__ = inheritsFrom.prototype;
inheritsFrom.apply( objectInstance, arguments );
return objectInstance;
so:
A new object is created, {}, to represent the new instance of the function
The prototype of the function is copied to __proto__ of the new object. Note that this is a copy-by-reference, so Foo.prototype and objectInstance.__proto__ now refer to the same object and changes made in one can be seen in the other immediately.
The function is called with this new object being set as this in the function
and whenever you try to access a function or property, e.g.: obj.bar(), the following logic gets run:
if( obj.hasOwnProperty('bar') ) {
// use obj.bar
} else if( obj.__proto__ ){
var proto = obj.__proto__;
while(proto){
if( proto.hasOwnProperty('bar') ){
// use proto.bar;
}
proto = proto.__proto__;
}
}
in other words, the following are checked:
obj.bar
obj.__proto__.bar
obj.__proto__.__proto__.bar
obj.__proto__.__proto__.__proto__.bar
... etc
until __proto__ eventually equals null because you've reached the end of the prototype chain.
Many browsers actually expose __proto__ now, so you can inspect it in Firebug or the Console in Chrome/Safari. IE doesn't expose it (and may very well have a different name for the same thing internally).