There are several things going on here.
First, before worrying about defining methods of objects, worry about the creation of objects.
So, there are several ways of creating objects. First, you can just create an inline object, out of the blue:
var obj = { property : "myProperty", func : function () {} };
You now have a brand new object.
You can extend that object by adding to it, after the fact.
obj.property02 = "myOtherProperty";
obj.otherFunc = function () { return this.property02; };
But the downfall of constructing inline objects is that all properties and methods are 100% public.
In order to deal with this, you can have a constructor function which creates and returns an object.
var MakeWallet = function (starting_amount, pin) {
var balance = 0,
wallet = {};
wallet.add = add_balance;
wallet.deduct = deduct_amount;
wallet.amount = check_balance;
return wallet;
function check_balance (pin) { /*...*/ }
function validate_pin (user_pin) { /*...*/ }
function add_balance (amount, pin) { /*...*/ }
function deduct_amount (amount, pin) { /*...*/ }
};
var myWallet = MakeWallet(1, 9274);
What do I get for my trouble?
ALL of the data is tamper-proof.
A user might still be able to rewrite wallet.deduct, but they won't actually get the real value of the pin, or get the amount in the wallet, or get any of the internal functions that I don't want them to have, including any internal security-numbers or entity/serial numbers I want to grant to track the wallet.
That's the benefit of building in this way.
Again, I can add methods and properties to the wallet, afterward:
myWallet.breakItOpen = function () { return this.balance; };
myWallet.stuffIt = function () { balance = 400000000; };
But neither of these things is actually going to have access to the variables or the functions inside of the original myWallet.
Only functions which existed at the time of creation will have access.
In other, more traditional creation-methods, you can use a class-like constructor function, using this.
function MakeWalletClass (starting_amount, pin) {
var balance = 0,
serial_and_pin = generate_serial() + "_" + pin;
this.balance = balance;
this.checkBalance = function () { return this.balance; };
}
var myWalletInstance = new MakeWalletClass(1, 1234);
But there's a problem:
myWalletInstance.balance is public.
Anybody can see it or change it.
Not good.
We could get around that by doing this:
function MakeWalletClass (starting_amount, pin) {
var balance = 0,
serial_and_pin = generate_serial() + "_" + pin;
this.checkBalance = function () { return balance; };
}
var myWalletInstance = new MakeWalletClass(1, 1234);
Now, this.checkBalance is reading the hidden balance variable, and not a publicly editable property.
Now, MakeWalletClass.prototype.
When you use the constructor pattern (ie: a function which adds properties to this and returns this, or doesn't return anything -- it returns this in the background -- and is called with the new keyword), adding prototype properties and methods will add properties and methods which are available to EVERY instance of the object you made.
So if your bank is called "The Bank of Bob", you could add:
MakeWalletClass.prototype.bankName = "The Bank of Bob";
Now every single instance of new MakeWalletClass(); will have a bankName property, and every one will be the exact-same value, and every one will be publicly available.
var yourWalletInstance = new MakeWalletClass(500, 2341);
yourWalletInstance.bankName; // "The Bank of Bob";
The prototype properties are even available on objects that you make before you add the property to the constructor function's prototype.
You can add prototype methods in the same way.
var myWalletInstance = new MakeWalletClass(1, 1234);
MakeWalletClass.prototype.getBalance = function () { return balance; };
myWalletInstance.getBalance(); // undefined;
Whoops!
It doesn't work.
Prototype functions have access ONLY to public properties (anything they can call with this.XXX).
So the upside of adding prototype properties is that they save a lot of memory.
If your program requires 3000 wallets, and you add a prototype function to the constructor, that function only exists 1 time in memory.
The downside of adding the prototype is that it can only do public things, so unless you want to make balance or pin public properties (hint: don't), prototypes are useless for private work.
So for those 3000 wallets, you need 3000 copies of any method that deals with balance or pin.
Now that you've got an understanding of all of that, and what prototype is for... the REAL difference between:
MakeWalletClass.prototype.say_bankName = function () { /*...*/ };
and
MakeWalletClass.say_bankName = function () { /*...*/ };
is that the prototype works on instances (wallet = new MakeWalletClass), and the method of MakeWalletClass doesn't -- it's only useful if you want a function attached to MakeWalletClass.
Maybe you want a function that returns the number of wallets made...
MyObjectdon't inherit properties in the constructor function but the properties in the constructor function's prototype.