- From: Brendan Eich <brendan@secure.meer.net>
- Date: Fri, 07 Jun 2013 12:35:42 +0100
- To: Boris Zbarsky <bzbarsky@MIT.EDU>
- CC: Jonas Sicking <jonas@sicking.cc>, DOM public list <www-dom@w3.org>, Anne van Kesteren <annevk@annevk.nl>, Cameron McCormack <cam@mcc.id.au>, "public-script-coord@w3.org" <public-script-coord@w3.org>
Boris Zbarsky wrote: > In ES, an argument is either "not passed" (as determined by > arguments.length) or has a value. Arguments with a default value can > in fact be "not passed" in that default values do not affect the > arguments object at all. For example: > > function f(arg = 5) { > alert(arg + " " + arguments[0]); > } > f(); > > alerts "5 undefined". Furthermore, even when an argument was passed > its default value will still kick in if undefined is passed. > > I'd like to claim that the ES semantics here where default values > don't affect the arguments object are pretty weird and seem like a > footgun when combined with call/apply on the arguments object, but I > assume there's a reason for them... A couple of reasons: 1. The arguments object should become legacy cruft with default and rest parameters, and the spread special form. These also take the heat off of apply (call is not relevant, right?). That is, if you have ES3 or ES5 code of this form: function f(a, b) { a = a || 4; b = b || 5; return g.apply(undefined, arguments); } The ES6 way to write it is to avoid arguments altogether: function f(a = 4, b = 5, ...r) { return g(a, b, ...r); } If you needed apply for |this| forwarding, you'd either make a new array: g.apply(this, [a, b, ...r]) -- or else indeed use call: g.call(this, a, b, ...r). 2. Implementations reflect actual parameters as arguments, with missing actuals excluded. Default parameters are sugar (I'm simplifying how scoping works) for ||=. So js> function f(a, b) { b = b || 42; print(Array.prototype.join.call(arguments)); } js> f(1) 1 js> f(1,2) 1,2 js> f(1,2,3) 1,2,3 it doesn't matter that b has an old-school default. > In any case, the question is how to reconcile the two sanely. Once > that's done, I fully expect the simplicity of the C++ implementation > here to be nonexistent. Ouch. But didn't TreatUndefinedAs in all its glory already do most of the damage? /be
Received on Friday, 7 June 2013 11:36:25 UTC