4

I am learning Object Oriented Java Script. I have below code for Factory Method.

function Foo() {
    var value = 1;
    return {
        method: function() {
            return value;
        },
        value:value
    }
}
Foo.prototype = {
    bar: function() {}
};

new Foo();
Foo();

method Foo can be called by two ways. new Foo(); or Foo(); Both do the same thing and output is same. what is actual difference in java script processing ?

onemach
  • 3,847
  • 5
  • 32
  • 47
Umesh Patil
  • 9,669
  • 15
  • 46
  • 76
  • Note that setting `Foo.prototype = {something}` is pointless if you are going to return your own object from the `Foo()` function rather than going with the object that JS creates for you when you say `new Foo()`. – nnnnnn Jan 03 '12 at 03:47
  • 2
    @Bakudan - JavaScript is object-oriented by any reasonable definition of the term. – Wayne Jan 03 '12 at 03:55
  • @Bakudan, If you have something to say(Object Oriented vs Object Based), justify it with example in new Answer. It will help newbies :) – Umesh Patil Jan 03 '12 at 03:59
  • @onemach, you can contribute in answer, rather than spelling error :) – Umesh Patil Jan 03 '12 at 04:30
  • Not worthy of its own answer probably, but notice that `new Foo` won't have a property `bar`. When using `new`, if you don't return an object, `Foo.prototype` is returned. Since you're creating an object literal in each invocation, it is returned instead. – Zirak Jan 03 '12 at 04:40

4 Answers4

3

In normal cases, new should be used when creating objects from a constructor function and eschewed when performing any other function call. When using new on a function 1) a new object is created; 2) the function is called with the value of this bound to that new object, and 3) the value returned from the function (by default) is the object created in step one.

However, in your case you're returning a completely new object from the "constructor" (different from the object in 1) above), which means there is no practical difference. The value of this will still be different inside the function, but both of these will return false:

new Foo() instanceof Foo;
Foo() instanceof Foo;

To illustrate the this difference, add the following to Foo:

alert(this instanceof Foo)

When called with new this alerts true; when called without it, false.

Furthermore, there's no point in assigning an object to Foo.prototype because you'll never create any instances of Foo that would make use of it (because, again, you're returning something completely different from Foo).

If you're going to return a custom object from Foo then you should prefer the version without new; there's no point in creating a new instance of Foo if you're going to ignore it and return something completely different, anyway.

Wayne
  • 56,476
  • 13
  • 125
  • 118
  • Yes. I tested both returns false. Any little example of "The value of this will be different inside the function" ? – Umesh Patil Jan 03 '12 at 03:36
  • Its better explanation. new creates the instance of Foo, whereas without new keeps just a static Object, that can be used anytime. correct ? – Umesh Patil Jan 03 '12 at 03:44
  • Further, setting `Foo.prototype` becomes pointless since the objects you create are not instances of `Foo`. – nnnnnn Jan 03 '12 at 03:48
  • @nnnnnn - Yeah, I was just thinking about making a similar comment. I think I'll update my answer. Thanks. – Wayne Jan 03 '12 at 03:49
2

Here's a great link:

Is Javascript "new" considered harmful?

See also:

http://phabricator.com/docs/phabricator/article/Javascript_Pitfalls.html

But here's the best link (and, really, the answer to your question:

http://www.crockford.com/javascript/inheritance.html

JavaScript is a class-free, object-oriented language, and as such, it uses prototypal inheritance instead of classical inheritance. This can be puzzling to programmers trained in conventional object-oriented languages like C++ and Java...

Community
  • 1
  • 1
paulsm4
  • 99,714
  • 15
  • 125
  • 160
1

The javascript new keyword in functions is pretty weird. The best (only?) in depth explanation of what is happening I've been able to find is actually this SO answer from Daniel Howard.

Should be required reading for anyone trying to learn some of the more advanced concepts of Javavscript.

By the way, you can get really far in js by never using the new keyword at all. Notice how basically none of the code using jquery relies on it.

Community
  • 1
  • 1
George Mauer
  • 103,465
  • 117
  • 349
  • 581
0

Because you are returning an object from Foo, the use of new has no effect. The return values of Foo() and new Foo() will not be instances of Foo; instead, they'll be instances of the type of whatever value you returned.

This same behavior is seen if you return any† object or any function from your constructor. However, if Foo were to return:

  • A string
  • A number
  • null
  • undefined (same as returning nothing at all)
  • or this

...then the return value of new Foo() would be an instance of Foo.

You can test out the code below on JSFiddle:

function ReturnsString() { return "string"; }
function ReturnsNumber() { return 1; }
function ReturnsNull() { return null; }
function ReturnsUndefined() { return void 0; }
function ReturnsThis() { return this; }
function ReturnsFunction() { return function() {}; }
function ReturnsObject() { return {}; }

alert("Results:"
    + "\nReturnsString: " + (new ReturnsString() instanceof ReturnsString)
    + "\nReturnsNumber: " + (new ReturnsNumber() instanceof ReturnsNumber)
    + "\nReturnsNull: " + (new ReturnsNull() instanceof ReturnsNull)
    + "\nReturnsUndefined: " + (new ReturnsUndefined() instanceof ReturnsUndefined)
    + "\nReturnsThis: " + (new ReturnsThis() instanceof ReturnsThis)
    + "\nReturnsFunction: " + (new ReturnsFunction() instanceof ReturnsFunction)
    + "\nReturnsObject: " + (new ReturnsObject() instanceof ReturnsObject)
);

The ReturnsFunction and ReturnsObject constructors will both show a false result, meaning they don't return an instanceof themselves when used with the new operator.

All of the other constructors do return an instanceof themselves when used with the new operator.

† Except this, as I mentioned above

aeskr
  • 3,376
  • 1
  • 13
  • 10
  • You mean, functions & objects don't return instance of itself. So Foo() and new Foo() also doesn't. but, if they return something else. They are part of their own instance ! – Umesh Patil Jan 03 '12 at 04:23
  • @Umesh, that's exactly right. I find this behavior to be pretty unintuitive! Thank goodness for [Coffeescript](http://coffeescript.org/). ;) – aeskr Jan 03 '12 at 04:26