This question already has answers here:
Using Class Variables in Javascript
(2 answers)
Closed 7 years ago.
Edit: Thanks #Aadit M Shah for confirming.
function Apple () {}
Apple.someVar = null; // Class variable
Apple.prototype.someVar = null; // Instance variable
In class-based languages (i.e. Java) static members are created with a special syntax and can be used as if they were members of the class itself.
In JavaScript there is no special syntax to denote static properties. However you can implement such a classy behaviour by using constructor function and adding properties to it. Constructors, like all other functions, are objects and can have properties.
Let's see an example:
We have a constructor for Car, a static method for Car and an "instance" (prototype delegation) method for Car.
// constructor
var Car = function () {};
// a static method
Car.isShiny = function () {
return "bling bling";
};
// "instance" method added to the prototype
Car.prototype.setPrice = function (price) {
this.price = price;
};
As expected we can call the static method and the "instance" method.
// calling a static method
Car.isShiny(); // "bling bling"
// creating an instance and calling a method
var ford = new Car();
ford.setPrice(5000);
Calling an "instance" method statically won't work.
Similarly, calling a static method on an instance won't work.
typeof Car.setPrice; // "undefined"
typeof ford.isShiny; // "undefined"
There is a workaround for calling a static method on an instance. Define a prototype method, which references the static method.
Car.prototype.isShiny = Car.isShiny;
ford.isShiny(); // "bling bling"
However, this comes with a little complication that we need to be aware of. The keyword this, if used in the static method, will refer to either the Car constructor function or the ford instance, depending on who is the caller.
It is possible to have the same method called statically and non-statically. With the help of instanceof we can know how the method was called.
// constructor
var Car = function (price) {
this.price = price;
};
// a static method
Car.isShiny = function () {
// this always works
var msg = "bling bling";
if (this instanceof Car) {
// this only works if called non-statically
msg += ", it costs $" + this.price + '!';
}
return msg;
};
// a normal method added to the prototype
Car.prototype.isShiny = function () {
return Car.isShiny.call(this);
};
// static call
Car.isShiny(); // "bling bling"
//non static call
var benz = new Car('9999.99');
benz.isShiny(); // "bling bling, it costs $9999.99!"
The example illustrates the use of public static members. In JavaScript you can implement private static members too.
Reference: JavaScript Patterns book.
JavaScript is a functional language and features of classical programming languages are not directly supported but can be achieved by the concept of closures.
In the code snippet you gave, both Apple.someVar and Apple.prototype.someVar will have the same value for all objects created from the Apple constructor function, i.e. like a class variable.
To achieve the functionality of instance variables, use closures.
You can look online for more help on closures, here's reference http://javascript.crockford.com/private.html
I am providing a small code snippet to to make it clear.
function Apple(property){
var color = property.color; //instance variable
this.getColor = function(){
return color;
};
}
Apple.type = "fruit"; //class variable
var redApple = new Apple({color:'red'});
var greenApple = new Apple({color:'green'});
both the variables redApple and greenApple share the same property 'type' but each has its own color property.
tl;dr
function Apple () {}
Apple.someVar = null; // property on the constructor - doesn't affect instances
Apple.prototype.someVar = null; // the default value of the `someVar` property on instances returned by the constructor when using the `new` keyword
Here is a more verbose example to see it in action:
function Apple () {}
Apple.color = 'blue'; // this doesn't do what you think it does.
console.log('Apple.color:', Apple.color); // blue
console.log('---');
// basic instantiation of the apples
var goldenDelicious = new Apple();
var grannySmith = new Apple();
var fuji = new Apple();
console.log('goldenDelicious.color:', goldenDelicious.color); // undefined
console.log('grannySmith.color:', grannySmith.color); // undefined
console.log('fuji.color:', fuji.color); // undefined
console.log('---');
fuji.color = 'red';
Apple.prototype.color = 'green';
// overrides color properties of all apples that have not
// had their color set - even those of instances already created
// This is because their value is the default, and we are
// modifying that default.
console.log('goldenDelicious.color:', goldenDelicious.color); // green
console.log('grannySmith.color:', grannySmith.color); // green
console.log('fuji.color:', fuji.color); // red
console.log('---');
// assign some actual colors
goldenDelicious.color = 'yellow';
grannySmith.color = 'green';
fuji.color = 'red';
console.log('goldenDelicious.color:', goldenDelicious.color); // yellow
console.log('grannySmith.color:', grannySmith.color); // green
console.log('fuji.color:', fuji.color); // red
console.log('---');
Apple.prototype.color = 'orange'; // all new apples will default to orange
var honeyCrisp = new Apple();
console.log('goldenDelicious.color:', goldenDelicious.color); // yellow
console.log('grannySmith.color:', grannySmith.color); // green
console.log('fuji.color:', fuji.color); // red
console.log('honeyCrisp.color:', honeyCrisp.color); // orange
Related
How do I add properties to a constructor function in JavaScript? For example. If I have the following function.
function Hotel(name)
{
this.name = name;
};
var hotel1 = new Hotel('Park');
can I add a "local" variable that can be used locally within the class as if it were private with the same notation using the keyword "this". Of course it would not be private since objects created will be able to use it correct?
Can I do something like this. Do I use the this keyword or do I use the var keyword
which one is it? I have example 2 on the function constructor on the bottom
1. var numRooms = 40;
2. this.numRooms = 40;
3. numRooms : 40,
function Hotel(name)
{
this.name = name;
this.numRooms = 40;
};
I know that if I want a function within the object constructor I need to use the this word. Will that work as well for normal variables as I have asked above.
function Hotel(name)
{
this.name = name;
this.numRooms = 40;
this.addNumRoomsPlusFive = function()
{
return this.numRooms + 5;
}
};
You can simple add a private variable to your constructor:
function Hotel(name) {
var private = 'private';
this.name = name;
};
But if you will use your Hotel function without a new operator, all properties and functions which was attached to this will become global.
function Hotel(name) {
var private = 'private';
this.name = name;
};
var hotel = Hotel('test');
console.log(name); // test
It is good idea to return an object in constructor function:
function Hotel(name) {
var
private_var = 'private',
private_func = function() {
// your code
};
retur {
name: 'name',
public_func: private_func
}
};
var hotel = Hotel('test');
console.log(name); // undefined
So if you will use Hotel constructor without new operator no global variable will be created. This is possible only if the return value is an object. Otherwise, if you try to return anything that is not an object, the constructor will proceed with its usual behaviour and return this.
can I add a "local" variable that can be used locally within the class as if it were private with the same notation using the keyword "this".
Yes we can:
// API implementation in the library
function Hotel(name) {
// only our library code knows about the actual value
const numRooms = 'privateNoRoomsVar';
this.name = name;
this[numRooms] = 40;
this.addNumRoomsPlusFive = function() {
return this[numRooms] + 5;
}
};
// from the library user's perspective
const hotel = new Hotel('Transylvania');
console.log('rooms+5 =', hotel.addNumRoomsPlusFive());
console.log('hotel.numRooms =', hotel.numRooms); // undefined
// also, users don't have access to 'numRooms' variable so they can't use hotel[numRooms].
If a user looks at the source code and finds out the value privateNoRoomsVar, then they can misuse the API.
For that we need to use symobls:
// API implementation in the library
function Hotel(name) {
// no one can duplicate a symbol so the variable is really private
const numRooms = Symbol();
this.name = name;
this[numRooms] = 40;
this.addNumRoomsPlusFive = function() {
return this[numRooms] + 5;
}
};
// from the library user's perspective
const hotel = new Hotel('Transylvania');
console.log('rooms+5 =', hotel.addNumRoomsPlusFive());
console.log('hotel.numRooms =', hotel.numRooms); // undefined
// there is no way users will get access to the symbol object so the variable remains private.
Private class features, #privateField, are supported by all the browsers so we don’t have to worry about this anymore.
// API implementation in the library
class Hotel {
// private field
#numRooms = 40;
constructor(name) {
this.name = name;
}
addNumRoomsPlusFive() {
return this.#numRooms + 5;
}
};
// from the library user's perspective
const hotel = new Hotel('Transylvania');
console.log('rooms+5 =', hotel.addNumRoomsPlusFive());
console.log('hotel.numRooms =', hotel.numRooms); // undefined
//console.log('hotel.numRooms =', hotel.#numRooms); // throws error
Javascript historically creates objects from prototypes of other objects. It was a result of EMCA2015, that you have a distinct syntax of a class that specifies an object. As an aside, if you mouse over the table in that link it gives dates of when the feature was implemented.
A javascript object created by the new operator is more or less a combination of an associative array ( what you make with let avar={}; ) that can access the function level scopes it is defined in. The keys of the array are its properties. According to its creator, Javascript was created to be an easy to use program language without a hierarchy of types. One of the ways it accomplished this is by more or less considering its mapping type to be equivalent to the prototypical Object which object oriented programming languages describe.
Adding properties in 2022
function AProtoype(arg1, arg2, arg3){
//this defines a property
this.pa=arg1;
/* unicorns in this section */
let x = 1;
/*
a getter which has the same syntax as a property
but returns x from the scope which it references and
not the object.
*/
get getx() => x;
}
let object = new AProtoype(2,3,4);
Is equivalent to the following code for the purposes of data access but not inheritance and typing. The new operator also sets variables on an object that are used for these purposes.
function NewObject(arg1, arg2, arg3){
let prototype = {};
/*dragons in this section, as you are not using the this keyword to accomplish things*/
prototype.pa = arg1;
Object.defineProperty(prototype, "getx", {get:()=>x});
return prototype;
}
//If you do this instead of using the new operator it is an anti-pattern.
//And like all anti-patterns: "But it works!"
let object = NewObject(2,3,4);
The relevant property defining methods where in some sense supported as early as 2010, 2011. I do not have a contemporary source to that time to confirm if you could pull off what I'm doing though, and you'd only want to if all else failed and it needed to run on Internet Explorer 9. In the event all else is failing, you may want to read the documentation for Object.create, which is also of interest because more or less provides an api to make new objects.
Now, for a fun time and horror, you can also define a function that returns this, and get an object back with an equivalent binding of that function. The horror comes when it is an object in global scope, and you rename a property of that object; as Javascript will resolve the name collision by happily writing on whatever it finds if it can. You can then use this to re-implement the prototype pattern that javascripts new operator is built off of conceptually, for the sake of science.
When you use a "constructor function" in Javascript, any properties defined on the instance using the this keyword become public. This is unavoidable, because Javascript objects have no concept of private properties - if it exists, it can be accessed directly as object.property.
For example, if you tried to do as in the following snippet, mimicking a typical getter/setter pattern with a private variable in Java or C# (note that even if this worked, this is not idiomatic Javascript):
function MyObject(privateVar) {
this.privateVar = privateVar;
}
MyObject.prototype.getVar = function() {
return this.privateVar;
};
MyObject.prototype.setVar = function(newVal) {
this.privateVar = newVal;
};
then while you can indeed use the getter and setter to do as you expect, you can also just access and set the private variable directly! Demonstration:
function MyObject(privateVar) {
this.privateVar = privateVar;
}
MyObject.prototype.getVar = function() {
return this.privateVar;
};
MyObject.prototype.setVar = function(newVal) {
this.privateVar = newVal;
};
var obj = new MyObject(1);
// using public getter/setter
console.log(obj.getVar()); // 1
obj.setVar(2);
console.log(obj.getVar()); // 2
// using private variable directly - not intended to work
console.log(obj.privateVar); // 2
obj.privateVar = 3;
console.log(obj.getVar()); // 3 (using public API to get it to show that the direct update to the private variable also affects the intended public methods)
There is though a way to mimic the effect of private variables. They're not actually object properties - because, as I have just demonstrated, such are intrinsically public - but the same can be mimicked by:
not using a "constructor function" at all, but a regular function that happens to return an object. This is all a constructor function really does, anyway - the difference in JS is only syntactic, that you do not need to use the new keyword when you call the function. (Although you still can, if you really prefer - any function that returns an object can be called with new and behave in the same way as without it, although performance will likely suffer a little as the function would then construct a brand new object and throw it away. See MDN for a justification of these statements, particularly step 4.)
inside this function, using a regular variable as the private variable. This variable will be completely inaccessible from outside by the simple rules of scope, but you can still have the returned object retain access to it by the "magic" of closures.
Here is the above getter/setter example translated to this procedure, as well as demonstrations of it working. (I hasten to add again though, that this wouldn't be considered idiomatic code in Javascript.)
function makeObjectWithPrivateVar(privateVar) {
function getPrivateVar() {
return privateVar;
}
function setPrivateVar(newVal) {
privateVar = newVal;
}
return { getPrivateVar, setPrivateVar };
}
var obj = makeObjectWithPrivateVar(1);
// getter
console.log(obj.getPrivateVar()); // 1
// setter
obj.setPrivateVar(2);
// getter again to observe the change
console.log(obj.getPrivateVar()); // 2
// but how could we access the private var directly??
// answer, we can't
console.log(obj.privateVar); // undefined
console.log(privateVar); // ReferenceError, privateVar is not in scope!
Note finally though that it's rare in modern Javascript to use the function-based constructors in this style, since the class keyword makes it easier to mimic traditional class-based languages like Java if you really want to. And in particular, more recent browsers support private properties directly (you just have to prefix the property name with a #), so the initial code snippet translated into a class and using this feature, will work fine:
class MyObject {
#privateVar
constructor(privateVar) {
this.#privateVar = privateVar;
}
getVar() {
return this.#privateVar;
}
setVar(newVal) {
this.#privateVar = newVal;
}
}
var obj = new MyObject(1);
// using public getter/setter
console.log(obj.getVar()); // 1
obj.setVar(2);
console.log(obj.getVar()); // 2
// using private variable directly - now doesn't work
console.log(obj.privateVar); // undefined, it doesn't exist
// console.log(obj.#privateVar); // error as it's explicitly private, uncomment to see error message
Usually it's performed using closures:
var Hotel = (function() {
var numrooms=40; // some kind of private static variable
return function(name) { // constructor
this.numrooms = numrooms;
this.name = name;
};
}());
var instance = new Hotel("myname");
Alright, just looking at the question, it seems like it would matter, but lets look at a test I did.
So I created 3 constructor functions. I did the usual Car, then a Mazda, then a MX8 constructor. All of them inherit based on the code in the JSFiddle. Here is a shell of what I did, more detail can be found in the JSFiddle.
By the way I'm a big fan of Object.create which doesn't need any babysitting of anything.
var Car = function () {
//code here
}
var Mazda = function (type) {
this.type = type;
//more code here including a simple method test
}
var MX8 = function () {
//more code here
}
Mazda.prototype = new Car();
MX8.prototype = new Mazda("MX8");
var z = new MX8();
//refer to my JSFiddle
z.interior; // got correct interior
z.type; // got correct type ie model
z.warrantyInfo(); // method was correctly inherited
z.speed; // got correct speed
z.constructor === MX8; // false (unless I specify the constructor in the code of which is commented out in my JSFiddle)
short answer:
You need to explicitly set the constructor.
function Base() {}
function Derived() {}
// old prototype object is gone, including constructor property
// it will get however all the properties attached by Base constructor
Derived.prototype = new Base();
Derived.prototype.constructor = Derived;
Does it matter if my Object returns the wrong constructor?
Well, it depends on whether you're using that property or not. I'd say it's a good practice to keep the correct constructor.
Possible use case:
function getType (target) {
// name is empty unless you use the function declaration syntax
// (read-only property)
return target.constructor.name;
}
getType(new Derived()) // "Derived"
getType(new Base()) // "Base"
side note:
There are better ways of implementing inheritance in JS.
My favorite pattern is the following:
function Base (x) { this.x = x; }
function Derived (x, y) { Base.call(this, x); this.y = y; }
// creates an empty object whose internal "[[Prototype]]" property
// points to Base.prototype
Derived.prototype = Object.create(Base.prototype);
Derived.prototype.constructor = Derived;
The ideea behind Object.create is based on:
function create (proto) {
function f () {}
f.prototype = proto;
return new f();
}
The actual function Object.create is better because you can pass null as prototype, which doesn't work using the above code.
Anyway, you should watch this excellent playlist: Crockford on JavaScript.
can you please tell me how to do encapsulation in javascript .I have a class Name Car .I want to extend this class with B class .Secondly I want to override and overload the methods in java script.
Here is my fiddle
http://jsfiddle.net/naveennsit/fJGrA/
//Define the Car class
function Car() { }
Car.prototype.speed= 'Car Speed';
Car.prototype.setSpeed = function(speed) {
this.speed = speed;
alert("Car speed changed");
}
//Define the Ferrari class
function Ferrari() { }
Ferrari.prototype = new Car();
// correct the constructor pointer because it points to Car
Ferrari.prototype.constructor = Ferrari;
// replace the setSpeed method
Ferrari.prototype.setSpeed = function(speed) {
this.speed = speed;
alert("Ferrari speed changed");
}
var car = new Ferrari();
car.setSpeed();
can you explain these two lines
Ferrari.prototype = new Car();
This line show Ferrari is extend by car ?
Ferrari.prototype.constructor = Ferrari;
what is the used of this line ?
JS, by design does not provide a built-in way to manage the visibility of members of an object. but its flexible enough to allow us to do encapsulation.
Effective write up i found for you is http://www.codeproject.com/Articles/108786/Encapsulation-in-JavaScript
Ferrari.prototype = new Car()
This method adds Car poperties to the Ferrari's prototype. Whatever is returned by the Car(), is added to the existing Ferrari's prototype.
Ferrari.prototype.constructor = Ferrari
Prototype has a constructor property which is overriden by this call Ferrari.prototype = new Car(). This is manually resetting it again.
prototype and constructor object properties
I have edited your fiddle. http://jsfiddle.net/fJGrA/3/
Using closure in javascript you can hide elements within an object or function.
function foo(args){
//this is a private variable.
var _name = ""
return{
getname:function(){
return _name
}
}
}
bar = new foo()
// name can only be accessed from inside the foo function.
Whenever a variable is created with a var keyword within a function, it is accessible only in the scope of that function. Effectively, being private to it.
In JavaScript I see a few different ways, certain tasks can be performed within an object for example, the object Egg I have below.
Can anyone tell me the difference between each one, why I would use one and not the other etc
var Egg = function(){
//Properties
var shell = "cracked" // private property
this.shell = "cracked" // public property
shell: "cracked" // what is this??
//functions
function cook(){
//standard function
}
cook: function(){
//what kind of function is this?
}
//not sure what this is
details: {
//What is this? an array :S it holds 2 elements?
cost: 1.23,
make: 'Happy Egg';
}
}
Your code snippet isn't quite valid, but here are a few things it raises:
Property initializers, object initializers
You've asked what shell: cracked is. It's a property initializer. You find them in object initializers (aka "object literals"), which are written like this:
var obj = {
propName: "propValue"
};
That's equivalent to:
var obj = {};
obj.propName = "propValue";
Both of the above create an object with a property called propName which has a string value "propValue". Note that this doesn't come into it.
Functions
There are a couple of places where functions typically come into it vis-a-vis objects:
Constructor functions
There are constructor functions, which are functions you call via the new operator. Here's an example:
// Constructor function
function Foo(name) {
this.name = name;
}
// Usage
var f = new Foo("Fred");
Note the use of the keyword this in there. That's where you've seen that (most likely). When you call a constructor function via new, this refers to the new object created by the new operator.
this is a slippery concept in JavaScript (and completely different from this in C++, Java, or C#), I recommend these two (cough) posts on my blog:
You must remember this
Mythical methods
Builder/factory functions
You don't have to use constructor functions and new, another pattern uses "builder" or "factory" functions instead:
// A factory function
function fooFactory(name) {
var rv = {}; // A new, blank object
rv.name = name;
return rv;
}
// Usage
var f = fooFactory("Fred");
Private properties
You mentioned "private" properties in your question. JavaScript doesn't have private properties at all (yet, they're on their way). But you see people simulate them, by defining functions they use on the object as closures over an execution context (typically a call to a constructor function or a factory function) which contains variables no one else can see, like this:
// Constructor function
function EverUpwards() {
var counter = 0;
this.increment = function() {
return ++counter;
};
}
// Usage:
var e = new EverUpwards();
console.log(e.increment()); // "1"
console.log(e.increment()); // "2"
(That example uses a constructor function, but you can do the same thing with a factory function.)
Note that even though the function we assign to increment can access counter, nothing else can. So counter is effectively a private property. This is because the function is a closure. More: Closures are not complicated
Sure, Ben.
This sort of gets to the bottom of the dynamism of JavaScript.
First, we'll look at basics -- if you're coming from a place where you understand class-based languages, like, say, Java or C++/C#, the one that is going to make the most sense is the constructor pattern which was included very early on:
function Egg (type, radius, height, weight) {
// private properties (can also have private functions)
var cost = (type === "ostrich") ? 2.05 * weight : 0.35 * weight;
// public properties
this.type = type;
this.radius = radius;
this.height = height;
this.weight = weight;
this.cracked = false;
// this is a public function which has access to private variables of the instance
this.getCost = function () { return cost; };
}
// this is a method which ALL eggs inherit, which can manipulate "this" properly
// but it has ***NO*** access to private properties of the instance
Egg.prototype.Crack = function () { this.cracked = true; };
var myEgg = new Egg("chicken", 2, 3, 500);
myEgg.cost; // undefined
myEgg.Crack();
myEgg.cracked; // true
That's fine, but sometimes there are easier ways of getting around things.
Sometimes you really don't need a class.
What if you just wanted to use one egg, ever, because that's all your recipe called for?
var myEgg = {}; // equals a new object
myEgg.type = "ostrich";
myEgg.cost = "......";
myEgg.Crack = function () { this.cracked = true; };
That's great, but there's still a lot of repetition there.
var myEgg = {
type : "ostrich",
cost : "......",
Crack : function () { this.cracked = true; }
};
Both of the two "myEgg" objects are exactly the same.
The problem here is that EVERY property and EVERY method of myEgg is 100% public to anybody.
The solution to that is immediately-invoking functions:
// have a quick look at the bottom of the function, and see that it calls itself
// with parens "()" as soon as it's defined
var myEgg = (function () {
// we now have private properties again!
var cost, type, weight, cracked, Crack, //.......
// this will be returned to the outside var, "myEgg", as the PUBLIC interface
myReturnObject = {
type : type,
weight : weight,
Crack : Crack, // added benefit -- "cracked" is now private and tamper-proof
// this is how JS can handle virtual-wallets, for example
// just don't actually build a financial-institution around client-side code...
GetSaleValue : function () { return (cracked) ? 0 : cost; }
};
return myReturnObject;
}());
myEgg.GetSaleValue(); // returns the value of private "cost"
myEgg.Crack();
myEgg.cracked // undefined ("cracked" is locked away as private)
myEgg.GetSaleValue(); // returns 0, because "cracked" is true
Hope that's a decent start.
You are mixing syntaxes between object property declaration and simple javascript statements.
// declare an object named someObject with one property
var someObject = {
key: value
};
// declare an anonymous function with some statements in it
// and assign that to a variable named "someFunction"
var someFunction = function () {
// any javascript statements or expressions can go here
};
There's a key distinction in JavaScript between objects and functions. Objects hold a bunch of data (including functions), and functions can be used to make or modify objects, but they aren't inherently the same thing. OOP in JavaScript is based around using functions as classes. For example, take the following class:
Test = function(){
this.value = 5;
}
If you just call the function Test(), then nothing will happen. Even if you say var x = Test(), the value of x will be undefined. However, using the new keyword, magic happens! So if we say var x = new Test(), then now the variable x will contain a Test object. If you do console.log(x.value), it would print 5.
That's how we can use functions to make objects. There's also a key different in syntax--a function can contain any sort of JavaScript block you want, whether that's if statements or for loops or what have you. When declaring an object, though, you have to use the key: value syntax.
Hope that clears things up a little bit!
I am currently switching from AS3 to JavaScript.
I still have some trouble with understanding inheritance-concepts.
What I do not understand is why the following code is not working properly:
Base = function () {
this.coolVar = "great";
}
SmallControl = function () {
// Inheritance:
this.prototype = new Base();
this.prototype.constructor = SmallControl;
this.prototype.init = function(aMap) {
console.log('init');
console.log('coolVar?: ' + this.coolVar);
}
}
var foo = new SmallControl();
//foo.init(); // --> TypeError: foo.init is not a function
foo.prototype.init(); // --> works
If I put the prototype definitions outside of the "SmallControl"-Function everything works fine... but I don't understand that.
I think you want something like this:
// Create the super class
Base = function () {
this.coolVar = "great";
};
// Create the new class
SmallControl = function () {
};
// Set the prototype of SmallControl to be an instance of Base.
// This runs the Base constructor _immediately_ which sets up the variable
SmallControl.prototype = new Base();
// Add the init method to the SmallControl class
SmallControl.prototype.init = function(aMap) {
console.log('init');
console.log('coolVar?: ' + this.coolVar);
}
// Create an instance of SmallControl
var foo = new SmallControl();
foo.init();
prototype is only a meaningful property of constructors. The object's actual prototype (which is accessible in some environments as the property __proto__, but this is not portable) is set to be the constructor's prototype attribute at the time the object is constructed. Changes to the constructor's prototype (adding properties to the prototype) will be reflected in live objects, but not if you set Constructor.prototype to be a completely different object.
In your constructor, you're setting the prototype attribute of the constructed object (this). This attribute has no special meaning on something that's not a constructor function. When you set it outside of the function, you set it on the constructor function.