From: David Mark on 14 Jun 2010 22:19 On Jun 14, 10:08 pm, pedz <pedz...(a)gmail.com> wrote: > On Jun 14, 6:49 pm, Garrett Smith <dhtmlkitc...(a)gmail.com> wrote: > > > It is mentioned in the code guidelines doc in three places: > > >http://jibbering.com/faq/notes/code-guidelines/#design > > I was curious so I poked the link. The first bullet was not clear to > me. > > Why is: > > > goog.isDef = function(val) { > > return val !== undefined; > > }; > > a useless function? Because it is nothing but a strict comparison with a performance penalty (a function call). > > Also, reading a little further, the term "nonstandard" might be > avoided. The function statement, it says, is "nonstandard" but it is > in the 3 and 5 standards. > The key point is that it is "allowed" and > not "required" and it is that choice of the implementers that make it > a bad choice to use. It is best avoided if cross-browser compatibility is desired. > Calling something in the standards a nonstandard > isn't helping the unenlightened. Mentions do not make standards. Requirements do. I agree there is a lot of confusion out there as most developers do not read the specs carefully (if at all). For example, it seems like every time I tell a beginner that there is no standard for the window object, they cite a mention of it in the ES3 specifications, despite the fact that the document does not define host objects as anything but implementation- dependent. It is, after all, a *language* specification (and the unrelated DOM recommendations don't shed much light on that object either).
From: RobG on 15 Jun 2010 00:45 On Jun 14, 5:50 am, Asen Bozhilov <asen.bozhi...(a)gmail.com> wrote: > Dmitry A. Soshnikov wrote: > > "Note 1. ECMAScript. Bound functions." -- <URL:http://dmitrysoshnikov.com/notes/note-1-ecmascript-bound-functions/> > > The article is good and useful. > > | Function.prototype.bind (thisArg [, arg1 [, arg2, ...]]) > | 15.3.4.5 > | 4. Let F be a new native ECMAScript object . Seems to me "bind" would be better named "setThis" as that is more descriptive of what it does. It would also avoid a naming conflict with implementations of bind in existing libraries. But I guess I'm too late with that suggestion in regard to ECMAScript ed 5. -- Rob
From: Lasse Reichstein Nielsen on 15 Jun 2010 01:20 "Dmitry A. Soshnikov" <dmitry.soshnikov(a)gmail.com> writes: > On 14.06.2010 14:46, Dmitry A. Soshnikov wrote: >> (2) it's not possible to implement the spec's behavior in JavaScript of >> the `new` bound functions > > Yes, it's possible: <URL: http://bit.ly/aboVXU> -- implemented by > Bozhilov; I've updated the article. It's distinguishable from the correct behavior. If you use the bound function as a method of an instance created from it, then it will believe it to be a construct call, even if it isn't. The problem is that you can't identify a construct call programmatically. Testing whether "this" is an instance of the function being created can be faked. /L -- Lasse Reichstein Holst Nielsen 'Javascript frameworks is a disruptive technology'
From: Garrett Smith on 15 Jun 2010 03:00 On 6/14/2010 7:08 PM, pedz wrote: > On Jun 14, 6:49 pm, Garrett Smith<dhtmlkitc...(a)gmail.com> wrote: >> It is mentioned in the code guidelines doc in three places: >> >> http://jibbering.com/faq/notes/code-guidelines/#design > > I was curious so I poked the link. The first bullet was not clear to > me. > > Why is: > >> goog.isDef = function(val) { >> return val !== undefined; >> }; > > a useless function? > Yes. Not only is it is useless, it can lead to potential misuse. Compared to `val !== undefined`, `goog.isDef(val)` is less clear and less efficient. It could /potentially/ be useful would be in an iteration style pattern where a callback was needed however the way `goog.isDef` is organized indicates that it is not intended to be used in that manner, but instead as a general method to determine if a value is not undefined. To see how Google uses goog.isDef, I did a search for goog.isDef and came up with the following: http://code.google.com/p/doctype/wiki/ArticleCoordinates | Updated Nov 15, 2008 by pilgrim | Labels: is-article, about-dom | ArticleCoordinates | HOWTO deal with page coordinates (goog.math.Coordinates) | [...] | /** | * Class for representing coordinates and positions. | * @param {Number} opt_x Left | * @param {Number} opt_y Top | * @constructor | */ | goog.math.Coordinate = function(opt_x, opt_y) { | /** | * X-value | * @type Number | */ | this.x = goog.isDef(opt_x) ? Number(opt_x) : undefined; | | /** | * Y-value | * @type Number | */ | this.y = goog.isDef(opt_y) ? Number(opt_y) : undefined; | | }; goog.math.Coordinate first calls `goog.isDef(opt_x)`. As we've seen, `goog.isDef` checks to see if the value of `opt_x` is not undefined. If that is the case, then the value of opt_x is converted to a number, otherwise `this.x` is given value undefined. It is strange design to be giving `x` a value that could be any of: 1) a finite number, 2) NaN, or 3) undefined. If avoiding NaN was wanted, (as would happen for Number(undefined)), then the code fails on that account. Instead, it could have succeeded by using instead the built-in `isFinite` function. Example: this.x = isFinite(opt_x) ? Number(opt_x) : undefined; - and that could be changed to use the more efficient unary +, which uses the same type conversion algorithm ToNumber. Eliminating NaN values from being assigned to the object's `x` and `y` properties would change Coordinate.equals to return true where two Coorinates had both NaN values, which might make sense in what appears as an overengineered alternative to {x:0, y:1}. Google's goog.math.Coordinate provides a stellar example of why goog.isDef is useless. It achieves this by showing an example of how the abstraction reduces code clarity and makes the intent less clear. Instead, the function isFinite probably should have been used `isFinite`. (and ideally it would seem best to just use {x: 0, y: 0} on an as-needed basis). Although the function is useless, it is also potentially misleading. This is because the identifier is "isDef" could be interpreted as "is defined". The closest thing to describign "defined" in ECMAScript is [[HasProperty]], however this function does not make a determination about an object having a property; only that val !== undefined. The function is potentially misleading to a beginner who might use the function in lieu of the `in` operator to check property existence. I actually had a conversation about a year ago with a prominent javascript expert and contributor to YUI regarding a bug in YUI. The code in question was ObjectAssert.hasProperty. The problem came down to making the same false inference about "if obj.prop is undefined, then obj does not have a property prop". The problem function was calling YAHOO.lang.isUndefined, which does the same thing that the goog.isDef function does but in the positive sense (or negative sense, depending how you look at it). That is, it returns `val === undefined`. Like goog.isDef, YAHOO.lang.isUndefined does not check an object for the existence of property (that would require both the object and a property to be passed in). I noticed the problem when testing a "clone" type of function with an object that had a property with the value undefined. Although it may seem odd to give a property with value `undefined`, it can happen (as the goog.Math.Coordinate does). I wanted to make sure that the property had been cloned properly and the clone function was required to be able to handle that case. Realizing the problem in the YUI function, I filed a bug: | ObjectAssert.hasProperty -- provides inaccurate results. Instead of | checking for the presence of a property, Assert.hasProperty checks the | value. The author and his manager both wanted me prove what I'm saying with a testcase, should I actually want the bug fixed. Much easier, I found, was to just fix the bug myself. Using a similar strategy to YAHOO.lang.isUndefined, goog.isDef checks to see if the value is not undefined. If the code must determine if an object has a property, then goog.isDef(myObj.prop) will not provide that information. The reason it won't tell you if the object has the property is that the object could have a property, and the value could be undefined. That type of abstraction is not useful. It is a useless abstraction that requires explanation. What is worse is that it can actually be deceptive to those who don't know the difference between an object having a property with an undefined value and an object not having a property. In contrast val !== undefined is instantly recognizable to anyone who understands ECMAScript. > Also, reading a little further, the term "nonstandard" might be > avoided. The function statement, it says, is "nonstandard" but it is > in the 3 and 5 standards. The key point is that it is "allowed" and > not "required" and it is that choice of the implementers that make it > a bad choice to use. Calling something in the standards a nonstandard > isn't helping the unenlightened. No, a Function statement is not defined by either 3 or 5 editions. Function statement is a nonstandard syntax extension. Please take a look at the FAQ and see if that doesn't clear things up for you. http://jibbering.com/faq/#functionStatement Asen noted that function declaration appearing where only statements are allowed will result in a SyntaxError in BESEN and DMDScript. I plan to add that to the FAQ. Currently, we have: | Implementations that have the function statement extension process | Fze as a Statement, in order, while other known implementations | evaluate Fze upon entering the execution context that it appears in. | For consistent behavior across implementations, avoid function | statement; use either FunctionExpression or FunctionDeclaration | instead. I'd like to change the FAQ to mention that. Proposed: | Implementations that have the function statement extension process | Fze as a Statement, in order. Others, including JScript, evaluate Fze | upon entering the execution context that it appears in. Yet others, | notably BESEN and DMDScript, throw a SyntaxError. | | For consistent behavior across implementations, do not use function | statement; use either FunctionExpression or FunctionDeclaration | instead. Garrett
From: Garrett Smith on 15 Jun 2010 03:11
On 6/15/2010 12:00 AM, Garrett Smith wrote: > On 6/14/2010 7:08 PM, pedz wrote: >> On Jun 14, 6:49 pm, Garrett Smith<dhtmlkitc...(a)gmail.com> wrote: >>> It is mentioned in the code guidelines doc in three places: >>> >>> http://jibbering.com/faq/notes/code-guidelines/#design >> >> I was curious so I poked the link. The first bullet was not clear to >> me. >> >> Why is: >> >>> goog.isDef = function(val) { >>> return val !== undefined; >>> }; >> >> a useless function? >> > > Yes. Not only is it is useless, it can lead to potential misuse. > Correction: Not only is it useless... > > It is strange design to be giving `x` a value that could be any of: 1) a > finite number, 2) NaN, or 3) undefined. If avoiding NaN was wanted, (as > would happen for Number(undefined)), then the code fails on that > account. Instead, it could have succeeded by using instead the built-in > `isFinite` function. Example: > Sorry, Number(undefined) results in NaN, but that would not happen because that case is covered by goog.isDef. Number(NaN) and cases where `opt_x` is not undefined, but converts to NaN are not covered. If disallowing NaN values to be assigned to the `x` and `y` properties is wanted, the code fails. Garrett |