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