2

There seems to be quite a few techniques out there for creating client side objects. What I find really confusing is determining what each technique is called. I've used prototype before

MyObject.prototype.someMethod = function (e, a) {
      .....
};

But I've also seen objects created in different like this

MyObject.someMethod = function () {
      ....
}

What is the second techinque called and why would one use one over the other?

5
  • It's attaching a property directly to the constructor function, objects constructed with MyObject don't inherit properties in the constructor function but the properties in the constructor function's prototype. Commented Aug 3, 2012 at 17:51
  • 1
    Neither of these relate to OOP at all. They accomplish different things. Commented Aug 3, 2012 at 17:52
  • A property of an object? Commented Aug 3, 2012 at 17:52
  • 1
    Read/learn this: eloquentjavascript.net/chapter8.html Commented Aug 3, 2012 at 17:52
  • possible duplicate of Declaring javascript object method in constructor function vs. in prototype Commented Aug 5, 2012 at 8:13

4 Answers 4

4

The first example is analogues to defining methods on a class. Every instance of the class uses the same code; this in such a method points to the instance on which the method was invoked.

The second is analogous to defining a static method on a class. You invoke the method like

MyObject.someMethod();

It doesn't make sense to invoke the method on an instance.

I guess you could call the first "prototype methods" and the second "constructor/class methods".

If you are comfortable using classical OO terminology when talking about javascript, which is somewhat awkward as Javascript uses prototypal inheritance, you can call the the first "instance methods" and the second "static methods".

Sign up to request clarification or add additional context in comments.

1 Comment

Awesome! I can't tell how much I've searched the internet for such a simple explanation.
1

The simplest answer is that using the prototype keyword to define a method on an object will allow that method to be used on all objects which inherit from it.

There are no classes in JavaScript, but you can emulate inheritance through the use of the prototype object (property).

myObject.prototype.method will add a "method" to ALL objects derived from myObject (you can do this to jQuery after jQuery has loaded -- $.prototype.method [$.fn.method] would add a method to all jQuery objects regardless of when they are/were created).

myObject.method will only add a "method" to myObject as it was at the time that line of code was executed (a static method). Any myObject invoked before this line executes will not have access to "method".

Comments

1

Javascript uses what's called Prototypical Inheritance to implement inheritance of traits. Consider the following example:

Superclass = function() {
   //constructor code
}

Superclass.prototype.toString=function() {
    return "Derp!";
}
Superclass.derp= function(){return 'herp!'}



var instance = new Superclass();
instance.toString();//valid
instance.derp();//fails

Comments

1

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...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.