|
12
|
So I think during the last meeting it was decided that we'd now have two
scopes for functions with default param values: One for head/params, and
one for the function body.
Was it also agreed that we'd use let-binding (vs var-binding) for the
default-value expressions?
I also just wanted to clarify some of the awkward edge-case scenarios as
I understand them to be sure we're all on the same page:
var x=1, y=2;
function foo(x=3, y=y, z=y) {
return [x, y, z];
}
foo(); // [3, undefined, undefined] ? or [3, 2, 2] ?
foo(2); // [2, undefined, undefined];
foo(2, 3); // [2, u];
x; // 1
y; // 2
var x = 1, y=2;
function foo(x=3,y=x+1) {
return [x, y];
}
foo(); // [3, 4];
foo(2); // [2, 4];
foo(2, 3); // [2, 3];
x; // 1
y; // 2
var x = 1, y=2;
function foo(x=3, y=(x=undefined,4)) {
return [x,y];
}
foo(); // [undefined, 4]
foo(2); // [undefined, 4]
foo(2, 3); // [2, 3] ? or [undefined, 3] ?
x; // 1
y; // 2
function foo(bar=(function() { return 'param-inner'; })) {
var ret = bar();
function bar() {
return 'body-inner';
}
return ret;
}
foo(); // 'body-inner'
foo(function() { return 'futility'; }); // 'body-inner'
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
|
|
Typo in first scenario fixed
On 9/30/13 1:17 PM, Jeff Morrison wrote:
> So I think during the last meeting it was decided that we'd now have
> two scopes for functions with default param values: One for
> head/params, and one for the function body.
> Was it also agreed that we'd use let-binding (vs var-binding) for the
> default-value expressions?
>
> I also just wanted to clarify some of the awkward edge-case scenarios
> as I understand them to be sure we're all on the same page:
>
> var x=1, y=2;
> function foo(x=3, y=y, z=y) {
> return [x, y, z];
> }
> foo(); // [3, undefined, undefined] ? or [3, 2, 2] ?
> foo(2); // [2, undefined, undefined];
> foo(2, 3); // [2, undefined, undefined];
> x; // 1
> y; // 2
>
>
> var x = 1, y=2;
> function foo(x=3,y=x+1) {
> return [x, y];
> }
> foo(); // [3, 4];
> foo(2); // [2, 4];
> foo(2, 3); // [2, 3];
> x; // 1
> y; // 2
>
>
> var x = 1, y=2;
> function foo(x=3, y=(x=undefined,4)) {
> return [x,y];
> }
> foo(); // [undefined, 4]
> foo(2); // [undefined, 4]
> foo(2, 3); // [2, 3] ? or [undefined, 3] ?
> x; // 1
> y; // 2
>
>
> function foo(bar=(function() { return 'param-inner'; })) {
> var ret = bar();
> function bar() {
> return 'body-inner';
> }
> return ret;
> }
> foo(); // 'body-inner'
> foo(function() { return 'futility'; }); // 'body-inner'
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
|
|
var f = function(a=this){} would transpile to something like: var f = (function(){ function __funcHead__(){ a=this; } function __funcBody__(){ // do stuff }
var a;
return function(a){__funcHead__.apply(this, arguments);return __funcBody__.call(this)}
}());
If my interpretation is correct.
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
|
|
On 9/30/2013 7:34 PM, Matthew Robb wrote:
> var f = function(a=this){}
>
> would transpile to something like:
>
> var f = (function(){
>
> function __funcHead__(){
> a=this;
> }
> function __funcBody__(){
> // do stuff
> }
>
> var a;
>
> return function(a){__funcHead__.apply(this, arguments);return
> __funcBody__.call(this)}
>
> }());
>
> If my interpretation is correct.
>
Not exactly. We're talking about lexical scopes, not function scopes.
|this| applies at the function scope (aside from global and arrowfunc
scope).
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
|
|
On 9/30/2013 3:51 PM, Dmitry Soshnikov wrote:
> Just re-read meeting notes, OK, cool on two scopes (seems like they
> are not in the spec yet). Want to double-check though: whether it will
> be possible to transpile now to ES3? From what I've seen in the notes,
> the head-scope will be able to access `this` value of the activation,
> etc. Not sure how to transpile now. Could someone give an example of a
> wrapper scope please, and confirm whether it's transpilable now?
I believe it is transpilable if you use an inner function scope. Someone
correct me if my translations are semantically incorrect:
ES6:
```js
var x = 1, y = 2;
function foo(x = 3, y = y, z = y) {
return [x, y, z];
}
```
ES3:
```js
var x = 1, y = 2;
function foo(x, y, z) {
// defaults
if (x === undefined) {
x = 3;
}
if (y === undefined) {
y = y; // essentially a no-op
}
if (z === undefined) {
z = y;
}
// body
return (function(x, y, z){
return [x, y, z];
}).call(this, x, y, z);
}
```
ES6:
```js
var x = 1, y=2;
function foo(x=3, y= (x = undefined, 4)) {
return [x,y];
}
```
ES3:
```js
var x = 1, y=2;
function foo(x, y) {
// defaults
if (x === undefined) {
x = 3;
}
if (y === undefined) {
y = (x = undefined, 4);
}
// body
return (function(x, y) {
return [x, y];
}).call(this, x, y);
}
```
ES6:
```js
function foo(bar = function() { return 'param-inner' }) {
var ret = bar();
function bar() {
return 'body-inner';
}
return ret;
}
```
ES3:
function foo(bar) {
// defaults
if (bar === undefined) {
bar = function() { return 'param-inner'; };
}
// body
return (function(bar){
var ret = bar();
function bar() {
return 'body-inner';
}
return ret;
}).call(this, bar);
}
A clearer example of my own which I think demonstrates the scoping
better (or exposes a problem with my understanding):
ES6
```js
function foo(x, y = function() { return x }) {
x++;
return x + y();
}
foo(1); // is this 3 or 4?
```
ES3:
```js
function foo(x, y) {
// defaults
if (y === undefined) {
y = function() { return x };
}
// body
return (function(x, y) {
x++;
return x + y();
}).call(this, x, y);
}
foo(1); // 3
```
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
|
|
I'm actually now really curious what the following does:
```
function foo(x, y = (() => { arguments[0] = "foo"; return "bar" })()) {
return [x, y];
}
foo(5);
```
Arrow functions are not implicitly strict currently, right? If so, the
above should return `["foo", "bar"]`.
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
|
|
> Brandon Benvie <mailto: [hidden email]>
> September 30, 2013 8:48 PM
> I'm actually now really curious what the following does:
>
> ```
> function foo(x, y = (() => { arguments[0] = "foo"; return "bar" })()) {
> return [x, y];
> }
Easy: arguments is an early error in the body of an arrow.
http://wiki.ecmascript.org/doku.php?id=harmony:arrow_function_syntax/be
>
> foo(5);
> ```
>
> Arrow functions are not implicitly strict currently, right? If so, the
> above should return `["foo", "bar"]`.
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss>
> Brandon Benvie <mailto: [hidden email]>
> September 30, 2013 8:21 PM
>
>
> I believe it is transpilable if you use an inner function scope.
> Someone correct me if my translations are semantically incorrect:
>
>
> ES6:
> ```js
> var x = 1, y = 2;
> function foo(x = 3, y = y, z = y) {
> return [x, y, z];
> }
> ```
>
> ES3:
> ```js
> var x = 1, y = 2;
> function foo(x, y, z) {
> // defaults
> if (x === undefined) {
> x = 3;
> }
> if (y === undefined) {
> y = y; // essentially a no-op
> }
> if (z === undefined) {
> z = y;
> }
>
> // body
> return (function(x, y, z){
> return [x, y, z];
> }).call(this, x, y, z);
> }
> ```
>
>
> ES6:
> ```js
> var x = 1, y=2;
> function foo(x=3, y= (x = undefined, 4)) {
> return [x,y];
> }
> ```
>
> ES3:
> ```js
> var x = 1, y=2;
> function foo(x, y) {
> // defaults
> if (x === undefined) {
> x = 3;
> }
> if (y === undefined) {
> y = (x = undefined, 4);
> }
>
> // body
> return (function(x, y) {
> return [x, y];
> }).call(this, x, y);
> }
> ```
>
>
> ES6:
> ```js
> function foo(bar = function() { return 'param-inner' }) {
> var ret = bar();
> function bar() {
> return 'body-inner';
> }
> return ret;
> }
> ```
>
> ES3:
> function foo(bar) {
> // defaults
> if (bar === undefined) {
> bar = function() { return 'param-inner'; };
> }
>
> // body
> return (function(bar){
> var ret = bar();
> function bar() {
> return 'body-inner';
> }
> return ret;
> }).call(this, bar);
> }
>
>
>
>
> A clearer example of my own which I think demonstrates the scoping
> better (or exposes a problem with my understanding):
>
> ES6
> ```js
> function foo(x, y = function() { return x }) {
> x++;
> return x + y();
> }
>
> foo(1); // is this 3 or 4?
> ```
>
> ES3:
> ```js
> function foo(x, y) {
> // defaults
> if (y === undefined) {
> y = function() { return x };
> }
>
> // body
> return (function(x, y) {
> x++;
> return x + y();
> }).call(this, x, y);
> }
>
> foo(1); // 3
> ```
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss>
> Dmitry Soshnikov <mailto: [hidden email]>
> September 30, 2013 3:51 PM
>
> On Mon, Sep 30, 2013 at 1:17 PM, Jeff Morrison < [hidden email]
> <mailto: [hidden email]>> wrote:
>
> So I think during the last meeting it was decided that we'd now
> have two scopes for functions with default param values: One for
> head/params, and one for the function body.
>
>
> Just re-read meeting notes, OK, cool on two scopes (seems like they
> are not in the spec yet). Want to double-check though: whether it will
> be possible to transpile now to ES3? From what I've seen in the notes,
> the head-scope will be able to access `this` value of the activation,
> etc. Not sure how to transpile now. Could someone give an example of a
> wrapper scope please, and confirm whether it's transpilable now?
>
> Was it also agreed that we'd use let-binding (vs var-binding) for
> the default-value expressions?
>
> I also just wanted to clarify some of the awkward edge-case
> scenarios as I understand them to be sure we're all on the same page:
>
> var x=1, y=2;
> function foo(x=3, y=y, z=y) {
> return [x, y, z];
> }
> foo(); // [3, undefined, undefined] ? or [3, 2, 2] ?
> foo(2); // [2, undefined, undefined];
> foo(2, 3); // [2, u];
> x; // 1
> y; // 2
>
>
> var x = 1, y=2;
> function foo(x=3,y=x+1) {
> return [x, y];
> }
> foo(); // [3, 4];
> foo(2); // [2, 4];
> foo(2, 3); // [2, 3];
> x; // 1
> y; // 2
>
>
> var x = 1, y=2;
> function foo(x=3, y=(x=undefined,4)) {
> return [x,y];
> }
> foo(); // [undefined, 4]
> foo(2); // [undefined, 4]
> foo(2, 3); // [2, 3] ? or [undefined, 3] ?
> x; // 1
> y; // 2
>
>
> function foo(bar=(function() { return 'param-inner'; })) {
> var ret = bar();
> function bar() {
> return 'body-inner';
> }
> return ret;
> }
> foo(); // 'body-inner'
> foo(function() { return 'futility'; }); // 'body-inner'
>
>
> Good examples, but in order to answer I need to see the exact
> structure of the head-scope. Because of `this` value I'm afraid it
> won't be static-time transformable or something.
>
> Dmitry
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss> Jeff Morrison <mailto: [hidden email]>
> September 30, 2013 1:17 PM
> So I think during the last meeting it was decided that we'd now have
> two scopes for functions with default param values: One for
> head/params, and one for the function body.
> Was it also agreed that we'd use let-binding (vs var-binding) for the
> default-value expressions?
>
> I also just wanted to clarify some of the awkward edge-case scenarios
> as I understand them to be sure we're all on the same page:
>
> var x=1, y=2;
> function foo(x=3, y=y, z=y) {
> return [x, y, z];
> }
> foo(); // [3, undefined, undefined] ? or [3, 2, 2] ?
> foo(2); // [2, undefined, undefined];
> foo(2, 3); // [2, u];
> x; // 1
> y; // 2
>
>
> var x = 1, y=2;
> function foo(x=3,y=x+1) {
> return [x, y];
> }
> foo(); // [3, 4];
> foo(2); // [2, 4];
> foo(2, 3); // [2, 3];
> x; // 1
> y; // 2
>
>
> var x = 1, y=2;
> function foo(x=3, y=(x=undefined,4)) {
> return [x,y];
> }
> foo(); // [undefined, 4]
> foo(2); // [undefined, 4]
> foo(2, 3); // [2, 3] ? or [undefined, 3] ?
> x; // 1
> y; // 2
>
>
> function foo(bar=(function() { return 'param-inner'; })) {
> var ret = bar();
> function bar() {
> return 'body-inner';
> }
> return ret;
> }
> foo(); // 'body-inner'
> foo(function() { return 'futility'; }); // 'body-inner'
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss>
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
|
|
On 9/30/2013 8:57 PM, Brendan Eich wrote:
> Easy: arguments is an early error in the body of an arrow.
Ok cool, that simplifies my previous examples a bit then. Instead of
using `call` and specifying the name of each argument, you can just use
`.apply(this, arguments)`.
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
|
|
> Brandon Benvie <mailto:bbenvie at mozilla.com>
> September 30, 2013 8:48 PM
> I'm actually now really curious what the following does:
>
> ```
> function foo(x, y = (() => { arguments[0] = "foo"; return "bar" })()) {
> return [x, y];
> }
Easy: arguments is an early error in the body of an arrow.
http://wiki.ecmascript.org/doku.php?id=harmony:arrow_function_syntax
/be
This restriction is not specified in the rev19 draft. Currently
arrow functions don't have an own `arguments` binding, but instead
access the outer functions `arguments` object, similar to `this`.
Disallowing the identifier "arguments" in PrimaryExpressions also
should imply disallowing "arguments" as a BindingIdentifier, which
shifts arrow functions again into "almost strict-mode".
- André
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
|
|
On 30 September 2013 22:17, Jeff Morrison < [hidden email]> wrote:
> So I think during the last meeting it was decided that we'd now have two
> scopes for functions with default param values: One for head/params, and one
> for the function body.
> Was it also agreed that we'd use let-binding (vs var-binding) for the
> default-value expressions?
I'm not entirely sure, actually. We discussed some pretty obscene
examples that would arise form doing a var-like thing, while nobody
came up with an example where it would be useful. I think in the end
the tendency was towards let-like, although I don't remember a formal
consensus. I assume let-like in my replies below.
> I also just wanted to clarify some of the awkward edge-case scenarios as I
> understand them to be sure we're all on the same page:
>
> var x=1, y=2;
> function foo(x=3, y=y, z=y) {
> return [x, y, z];
> }
All parameters are in scope in the default expressions, so y is never
going to resolve to the global var binding. Also, all defaults are
being evaluated and bound left to right.
For more examples, see also my slides, which weren't yet linked in the
meeting notes that Rick posted:
https://github.com/rwaldron/tc39-notes/blob/master/es6/2013-09/default-arguments.pdf> foo(); // [3, undefined, undefined] ? or [3, 2, 2] ?
> foo(2); // [2, undefined, undefined];
These two would throw, because y is used before being bound (just like
'let y=y' throws).
> foo(2, 3); // [2, undefined, undefined];
This one would be [2, 3, 3].
> x; // 1
> y; // 2
>
>
> var x = 1, y=2;
> function foo(x=3,y=x+1) {
> return [x, y];
> }
> foo(); // [3, 4];
> foo(2); // [2, 4];
No, [2, 3] for the latter.
> foo(2, 3); // [2, 3];
> x; // 1
> y; // 2
>
>
> var x = 1, y=2;
> function foo(x=3, y=(x=undefined,4)) {
> return [x,y];
> }
This one I really dislike. I had actually proposed to disallow
assignment to other parameters in default expressions, but that got a
lot of resistance.
> foo(); // [undefined, 4]
> foo(2); // [undefined, 4]
Yes.
> foo(2, 3); // [2, 3] ? or [undefined, 3] ?
[2, 3], the default expressions are not evaluated if the argument
isn't undefined.
> x; // 1
> y; // 2
>
>
> function foo(bar=(function() { return 'param-inner'; })) {
> var ret = bar();
> function bar() {
> return 'body-inner';
> }
> return ret;
> }
> foo(); // 'body-inner'
> foo(function() { return 'futility'; }); // 'body-inner'
Yes.
/Andreas
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
|
|
Just a quick one. I think the best representation in ES3 or 5 would be the following
```javascript function foo(x, y, z) { switch(arguments.length) {
case 0: x = 1; case 1: y = 2; case 2: z = 3; } // whatever logic involved, i.e. return x + y + z; } ```
no break and no default is meant.
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
|
|
No, we are using undefined actual parameter value, not argument.length,
to trigger defaulting -- as discussed many times and cited by me (again)
recently in reply to Oliver. Please do not go backward.
/be
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
|
|
On Oct 1, 2013, at 12:03 AM, André Bargull wrote:
> Brandon Benvie <mailto:bbenvie at mozilla.com>
> September 30, 2013 8:48 PM
> I'm actually now really curious what the following does:
>
> ```
> function foo(x, y = (() => { arguments[0] = "foo"; return "bar" })()) {
> return [x, y];
> }
Easy: arguments is an early error in the body of an arrow.
http://wiki.ecmascript.org/doku.php?id=harmony:arrow_function_syntax
/be
This restriction is not specified in the rev19 draft. Currently
arrow functions don't have an own `arguments` binding, but instead
access the outer functions `arguments` object, similar to `this`.
Disallowing the identifier "arguments" in PrimaryExpressions also
should imply disallowing "arguments" as a BindingIdentifier, which
shifts arrow functions again into "almost strict-mode".
- André
The restriction we want and how to enforce it is not all that clear.
We don't really want to have an "almost strict" mode for the body of arrow functions, if that was going to be the case I think it would be much better to simply say that arrow functions are always strict.
The spec. currently applies the static semantics of strict mode formal parameters (no duplicate names, can't name a parameter 'eval' or 'arguments') to arrow function formal parameters, but in all other ways both the formal parameter list (think default value expressions) and the arrow function body follow the strictness of the surrounding code.
that means things like the following are valid in non-strict arrow functions:
() => {function arguments() {}; return arguments} () => {let arguments =5; ...}
So we can't just statically disallow 'arguments' references in a ConciseBodu
Also, we have to have consistent behavior for an eval('arguments') that appears in a ConciseBody.
Here are possible reasonable alternatives for handling arguments in arrow functions:
1) nothing special, same rules as a FunctionExpression. An arguments object is available and strict/non-strict distinctions apply both statically and dynamically.
2) nothing special, but strict arguments object. Just like #1 except it always has a strict mode arguments object (no joining of augments elements and formal parameters
3) #2, plus strict mode parameter naming restrictions are also applied (no duplicates, can't use 'eval' or 'arguments' as parameter names)
4) no-arguments objects with shadowing, 'arguments' binds to undefined. Arrow functions do not have an arguments objects but they have an implicit constant binding of 'arguments' in their parameter scope whose value is undefined. References to 'arguments' in the body evaluate to undefined. (unless, non-strict and there are explicit declarations of the name 'arguments');
5) no-arguments objects with shadowing, 'arguments' is in temporal dead zone. Arrow functions do not have an arguments objects but they have an implicit binding of 'arguments' in their parameter scope that is never marked as initialized. References to 'arguments' in the body throw because they are temporal dead zone references. (unless, non-strict and there are explicit declarations of the name 'arguments' that shadow the parameter level binding);
6) nothing special, but no arguments object, normal lexical scoping. Like #1 except that there is no arguments object or local binding of 'arguments'. References to arguments resolve via the enclosing scope.
7) strict mode name restrictions, but no arguments object, normal lexical scoping. Like #3 except that there is no arguments object or local binding of 'arguments'. References to arguments resolve via the enclosing scope.
The rev19 spec. current has approximately #7 but there isn't anything final about that. It sounds to me like some think either #3 or #4 is the plan of record although I don't think we've talked about it at a TC39 meeting that this level of detail.
I think #3 would be a good solution. So is #7.
#3 probably would seem reasonable to JS programmers. #7 probably is what lexical scoping heads would expect. #4 or #5 is a completely new semantics that I don't think anyone expects.
Allen
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
|
|
I see. Does `null` count as undefined too or it must be explicitly undefined ? not that using a transpiler this matters much ... just curious about how the ES < 6 will look like.
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
|
|
3 and 7 both seems good. Personally I prefer #7 but I'm worried that
it might be too surprising that arguments refers to the outer
function.
On Tue, Oct 1, 2013 at 11:11 AM, Allen Wirfs-Brock
< [hidden email]> wrote:
>
> On Oct 1, 2013, at 12:03 AM, André Bargull wrote:
>
>> Brandon Benvie <mailto:bbenvie at mozilla.com>
>> September 30, 2013 8:48 PM
>> I'm actually now really curious what the following does:
>>
>> ```
>> function foo(x, y = (() => { arguments[0] = "foo"; return "bar" })()) {
>> return [x, y];
>> }
>
> Easy: arguments is an early error in the body of an arrow.
>
> http://wiki.ecmascript.org/doku.php?id=harmony:arrow_function_syntax>
> /be
>
>
> This restriction is not specified in the rev19 draft. Currently arrow
> functions don't have an own `arguments` binding, but instead access the
> outer functions `arguments` object, similar to `this`. Disallowing the
> identifier "arguments" in PrimaryExpressions also should imply disallowing
> "arguments" as a BindingIdentifier, which shifts arrow functions again into
> "almost strict-mode".
>
> - André
>
>
> The restriction we want and how to enforce it is not all that clear.
>
> We don't really want to have an "almost strict" mode for the body of arrow
> functions, if that was going to be the case I think it would be much better
> to simply say that arrow functions are always strict.
>
> The spec. currently applies the static semantics of strict mode formal
> parameters (no duplicate names, can't name a parameter 'eval' or
> 'arguments') to arrow function formal parameters, but in all other ways both
> the formal parameter list (think default value expressions) and the arrow
> function body follow the strictness of the surrounding code.
>
> that means things like the following are valid in non-strict arrow
> functions:
>
> () => {function arguments() {}; return arguments}
> () => {let arguments =5; ...}
>
> So we can't just statically disallow 'arguments' references in a ConciseBodu
>
> Also, we have to have consistent behavior for an
> eval('arguments')
> that appears in a ConciseBody.
>
> Here are possible reasonable alternatives for handling arguments in arrow
> functions:
>
> 1) nothing special, same rules as a FunctionExpression. An arguments object
> is available and strict/non-strict distinctions apply both statically and
> dynamically.
>
> 2) nothing special, but strict arguments object. Just like #1 except it
> always has a strict mode arguments object (no joining of augments elements
> and formal parameters
>
> 3) #2, plus strict mode parameter naming restrictions are also applied (no
> duplicates, can't use 'eval' or 'arguments' as parameter names)
>
> 4) no-arguments objects with shadowing, 'arguments' binds to undefined.
> Arrow functions do not have an arguments objects but they have an implicit
> constant binding of 'arguments' in their parameter scope whose value is
> undefined. References to 'arguments' in the body evaluate to undefined.
> (unless, non-strict and there are explicit declarations of the name
> 'arguments');
>
> 5) no-arguments objects with shadowing, 'arguments' is in temporal dead
> zone. Arrow functions do not have an arguments objects but they have an
> implicit binding of 'arguments' in their parameter scope that is never
> marked as initialized. References to 'arguments' in the body throw because
> they are temporal dead zone references. (unless, non-strict and there are
> explicit declarations of the name 'arguments' that shadow the parameter
> level binding);
>
> 6) nothing special, but no arguments object, normal lexical scoping. Like #1
> except that there is no arguments object or local binding of 'arguments'.
> References to arguments resolve via the enclosing scope.
>
> 7) strict mode name restrictions, but no arguments object, normal lexical
> scoping. Like #3 except that there is no arguments object or local binding
> of 'arguments'. References to arguments resolve via the enclosing scope.
>
> The rev19 spec. current has approximately #7 but there isn't anything final
> about that. It sounds to me like some think either #3 or #4 is the plan of
> record although I don't think we've talked about it at a TC39 meeting that
> this level of detail.
>
> I think #3 would be a good solution. So is #7.
>
> #3 probably would seem reasonable to JS programmers. #7 probably is what
> lexical scoping heads would expect. #4 or #5 is a completely new semantics
> that I don't think anyone expects.
>
> Allen
>
>
>
>
>
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss>
--
erik
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
|
|
I agree that the discussions as I remember them do not go into this level of detail. Thanks for being so explicit about precise choices.
However, I do recall that the consensus we had was enough to rule out #3, or indeed any solution where arrow functions have their own arguments object. And even if I recall wrongly, I do think arrow functions should not get their own arguments object -- that's too surprising from an arrow-function-as-smalltalk-block-like perspective.
#7 can be explained in a memorable way:
Generally variables are brought into scope by an explicitly appearing defining occurrence. Two exceptions are the "function" brings into scope both "this" and "arguments". These remain in scope until shadowed by a nested "function" or by an explicit definition. Note that "this" can never be explicitly defined, and "arguments" can only be explicitly defined in non-strict code.
As of ES6, a variety of other function-defining constructs, like "function", implicitly bring into scope a new "this" and "argument". Arrow-functions are not one of these. Within an arrow function, both "this" and "arguments" are lexically captured from the enclosing context.
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
|
|
I need to read everything Brendan suggested but if anyone would be so kind to refresh my memories on this arrow function I'd appreciate that. I don't need much more than yes/no as answer, thanks.
1. `var o = {method: () => this};` will o.method() return o ? (I guess nope)
Considering the following code:
```javascript var Proto = (function(){
this.method = () => this; return this.constructor; }.bind(function Proto() {}.prototype)); ``` 2. will it work as expected per each `new Proto` object ? (I guess nope, everything referred to Proto.prototype)
Considering the following code:
```javascript var o = {i: 0};
(function(O){
O.fatMethod = (i) => i + this.i;
O.justMethod = function (i) { return i + O.i; };
}.bind(o,O)); ```
3. will the `fatMethod` be ideally/theoretically/technically faster to execute once made hot through JIT capable engines (or made preventively hot since immutable in such form) ?
My bonus, humble, honest, and final question would be:
4. what kind of problem is this fat arrow feature trying to solve exactly, if it cannot be used for classes, direct methods assignment, but only for some runtime event assignment instead of using bind and still being unable to remove that listener later on ?
Thanks a lot in advance for any refreshing and/or enlightening answer, it's actually a while I am wondering this stuff.
Best Regards
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
|
12
|