On 12/26/10, fernando trasvina <trasv...@gmail.com> wrote:
>
> On Dec 26, 2010, at 2:36 AM, Garrett Smith wrote:
>
>> On 12/25/10, fernando trasvina <trasv...@gmail.com> wrote:
>>>
>>> On Dec 24, 2010, at 8:44 PM, Garrett Smith wrote:
>>>
>>>> On 12/24/10, fernando trasvina <trasv...@gmail.com> wrote:
>>>>>
>>>>> On Dec 24, 2010, at 6:43 PM, Garrett Smith wrote:
>>>>>
>>>>>> On 12/24/10, Michael Haufe (TNO) <t...@thenewobjective.com> wrote:
>>>>>>> On Dec 24, 3:05 pm, Garrett Smith <dhtmlkitc...@gmail.com> wrote:
>>>>>>>
>>>>>>>> I rather have it one way or the other. e.g.
>>>>>>>>
>>>>>>>> makePoint(x, y);
>>>>>>>>
>>>>>>>> - OR -
>>>>>>>>
>>>>>>>> new Point(x, y);
>>>>>>>>
>>>>>>>> I just don't like seeing any extra if/else in the code. I also don't
>>>>>>>> want to handle the case where somebody might be relying on an
>>>>>>>> anomaly
>>>>>>>> of calling the constructor as a function call.
>>>>>>>
>>>>>>> If defensive programming isn't necessary, of course. But since JS
>>>>>>> can't statically enforce such things it may be necessary to do so.
>>>>>>>
>>>>>> If a factory is used, then that's irrelevant. Toy example:
>>>>>>
>>>>>> function getAPoint(x, y) {
>>>>>>
>>>>>> }
>>>>>> The worst the client could do would be to use `new getAPoint`. That
>>>>>> would be a problem if the API expects `this` to be global object.
>>>>>>
>>>>>> Methods can be shared in scope, but the x and y properties can be
>>>>>> instance properties.
>>>>>>
>>>>>> function getAPoint(x, y) {
>>>>>> function distanceFromOrigin() {
>>>>>>  return Math.sqrt((this.x * this.x) + (this.y * this.y));
>>>>>> }
>>>>>> getAPoint = function(x, y) {
>>>>>>  return {
>>>>>>    x : x,
>>>>>>    y : y,
>>>>>>    distanceFromOrigin: distanceFromOrigin
>>>>>>  };
>>>>>> };
>>>>>> return getAPoint(x, y);
>>>>>> }
>>>>>> getAPoint(4, 0).distanceFromOrigin();
>>>>>
>>>>> I would say that coding this way should not be done unless there is an
>>>>> extreme requirement for it.
>>>>>>
>>>>>> The downside to that is `distanceFromOrigin` is hanging off the VO, so
>>>>>> it looks like a private static method, so what is `this`?
>>>>>>
>>>>>> It might be OK to "leak" a little implementation detail in this case:
>>>>>>
>>>>>> function getAPoint(x, y) {
>>>>>> function Point(x, y) {
>>>>>>  this.x = +x;
>>>>>>  this.y = +y;
>>>>>> }
>>>>>> Point.prototype = {
>>>>>>  distanceFromOrigin : function() {
>>>>>>    return Math.sqrt((this.x * this.x) + (this.y * this.y));
>>>>>>  }
>>>>>> };
>>>>>>
>>>>>> getAPoint = function(x, y) {
>>>>>>  return new Point(x, y);
>>>>>> };
>>>>>>
>>>>>> return getAPoint(x, y);
>>>>>> }
>>>>>
>>>>> this should be done this way. you should not be defining the
>>>>> constructor
>>>>> function every time you run your factory,
>>>>
>>>> You're making a statement about the code that is false. The example
>>>> uses a technique that is known as "function rewriting" or "russian
>>>> doll" or I've explained it with more elaboration below.
>>>>
>>>> this what is
>>>>> really doing is creating a new constructor function every time and
>>>>> building
>>>>> an instance for it completely useless because because
>>>>> then how would you do instanceof? never put this type of closures for
>>>>> factories unless really needed.
>>>>>
>>>>
>>>> Your conclusion follows your analysis, which unfortunately is
>>>> incorrect. Please see my explanation below.
>>>>
>>>>> var Point = function(){};
>>>>>
>>>>> var getAPoint = function(x,y){
>>>>>   return new Point(x,y);
>>>>> }
>>>>>
>>>> What's missing from that example?
>>>    are you making up a point of a rhetorical question in here? nothing is
>>> missing, you can run the code and get an instance of Point
>>>
>>
>> The Point constructor doesn't really do anything. It looks like you
>> forgot something. And you obviously forgot a semicolon after
>> `getAPoint`.
>
>      OMG really?

I don't like this style.

>      it does not matter what the constructor does, you get a correct object
>      really? a semicolon as the last statement of my code? does are errors?
>     please jslint my code, then run it then complain.

JSLint has nothing to do with the error. Most definitely JSLint can't
make sure you've written code that is a correct program.

[...]

>>>> Here is my explanation:
>>>>>>
>>>>>> The Point constructor is cached on the VO of the outer getAPoint.
>>>>>> Outer getAPoint identifier gets assigned to inner getAPoint identifier
>>>>>> but the scope chain of the inner getAPoint function has the Point
>>>>>> constructor and prototype.
>>>
>>> OMG lectures again?
>>>
>>
>> Well, if you don't want to learn it, then you don't have to.
>
>     no need to hear a lecture from a pointless example that its not solving
> anything you are just being too verbose to hide a variable.

The OP is asking about OO js. The subject has shifted quite naturally
to the module pattern, private/hidden members, and creating a private
delegate which used the Point constructor as a toy example to explain
the mechanics of doing that.

Again, the point of the `Point` example is to demonstrate the
mechanics of that. I am certain, however, that in my example, there is
only ONE `Point` constructor, that Point constructor is private, and
that contradictory to your claim, the `Point` constructor function is
not recreated, but is only created once.

Well you didn't acknowledge your mistake, I just hope I've explaine3d
function rewriting well enough so that it is not going to be confusing
to others. The function rewriting pattern is a bit tricky when you're
new to it.

>>
>>> just run your code
>>
>> Be sure, I run my code before posting.
>
>    ok then please notice that every time you get an instance of Point and
> never replaced getAPoint factory with inner factory so no memoization there
>   if no memoization then you will end up running all the code every time :)
>>

Ah no, you're wrong again.

>>>
>>> function getAPoint(x, y) {
>>> function Point(x, y) {
>>>  this.x = +x;
>>>  this.y = +y;
>>> }
>>> Point.prototype = {
>>>  distanceFromOrigin : function() {
>>>    return Math.sqrt((this.x * this.x) + (this.y * this.y));
>>>  }
>>> };
>>>
>>> getAPoint = function(x, y) {
>>>  return new Point(x, y);
>>> };
>>>
>>> return getAPoint(x, y);
>>> }
>>>
>> I ran that.
>>
>> I did not run the following, as it is not my code:
>    but that probes you are wrong, point should be always accessible because
> you should not hide you objects from their instances

First time I've heard that one. I don't suppose you have a reason for that.

>>> console.log(getAPoint(1,2)) //Object { x=1, y=2}
>>> console.log(getAPoint(1,2) instanceof Point) //false
>
>     the probe is this.  at the end you are just ending up with a hidden
> Point reference and the resultant code is my version of the code.
>

So your way is better because it is yours, huh? Hmm. The following
looks identical to the example I wrote.

>   function getAPoint(x, y) {
>   function Point(x, y) {
>    this.x = +x;
>    this.y = +y;
>   }
>
>   Point.prototype = {
>    distanceFromOrigin : function() {
>      return Math.sqrt((this.x * this.x) + (this.y * this.y));
>    }
>   };
>
>   getAPoint = function(x, y) {
>    return new Point(x, y);
>   };
>
>   return getAPoint(x, y);
> }
>

Is that my example or am I missing something?

OK, this is definitely your code:

> var point = getAPoint(1,1);
>
> console.log(point);
>
> console.log(getAPoint.toString())
>
>
> please run it, this is the output.
>
> Object { x=1, y=1}
> function (x, y) { return new Point(x, y); }
>

That looks as something that Firebug would pretty print.

>>>
>>
>> That's your code not mine. And it does not do what you said it does.
>> That code should result ReferenceError, as Point would not be resolved
>> there. Well, unless you added a separate Point constructor and got
>> yourself confused while typing into FB.
>
>
>     yes i ran your code and mine, i mixed up the references to Point. but
> either way my point is that hiding Point is useless and misleading.

Well, OK, then. So we disagree that having Point be hidden is a good
thing. In some cases it is useful to havea private constructor and use
a factory.

In most cases and in this case, an object's `constructor` doesn't
matter; what matters is what the object can do. E.g. if it has numeric
`x` and `y` properties is what matters -- the constructor? It doesn't
matter much.
-- 
Garrett

-- 
To view archived discussions from the original JSMentors Mailman list: 
http://www.mail-archive.com/jsmentors@jsmentors.com/

To search via a non-Google archive, visit here: 
http://www.mail-archive.com/jsmentors@googlegroups.com/

To unsubscribe from this group, send email to
jsmentors+unsubscr...@googlegroups.com

Reply via email to