From: David Mark on
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
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
"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
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
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