On 12/26/10, fernando trasvina <[email protected]> wrote:
>
> On Dec 26, 2010, at 2:36 AM, Garrett Smith wrote:
>
>> On 12/25/10, fernando trasvina <[email protected]> wrote:
>>>
>>> On Dec 24, 2010, at 8:44 PM, Garrett Smith wrote:
>>>
>>>> On 12/24/10, fernando trasvina <[email protected]> wrote:
>>>>>
>>>>> On Dec 24, 2010, at 6:43 PM, Garrett Smith wrote:
>>>>>
>>>>>> On 12/24/10, Michael Haufe (TNO) <[email protected]> wrote:
>>>>>>> On Dec 24, 3:05 pm, Garrett Smith <[email protected]> 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/[email protected]/
To search via a non-Google archive, visit here:
http://www.mail-archive.com/[email protected]/
To unsubscribe from this group, send email to
[email protected]