Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
909 views
in Technique[技术] by (71.8m points)

ecmascript 6 - Scope of Default function parameters in javascript

I'm playing with some EcmaScript 2015 features and I must say that specification is rather hard to understand.

I totally understand that this code should throw error of some kind:

(function(a = b, b = 1) { })();

And I know that default value could use outer scope:

(function() {
  let c = 1;
  return (function(a = c) { return a === 1; })();
})();

But I don't understand why these examples are not good:

(function() {
  let a = 1;
  (function(a = a) { })();
})();

(function() {
  let b = 1;
  (function(a = b, b = 2) { })();
})();

My Chrome 59.0.3071.115 throws ReferenceError that variable is not defined.

It seems that Chrome is doing some optimization where only 1 scope is created where all parameters set as inaccessible, and they are added one by one after their assignment.

Some proof of this could be:

(function(a = () => b, b = 2) { return a() === 2; })();

This looks like an missing opportunity for my taste and I'm wondering does specification force to use only 1 scope here or this is only v8 implementation details.

Could somebody please point me to place in specification which could clarify this?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I don't understand why these examples are not good

Because the default initialisers are not evaluated in the parent scope, but rather inside the function scope. The parameters themselves are already in scope, so that you can do something like

(function(a = 2, b = a) { console.log(b); }());

Could somebody please point me to place in specification which could clarify this?

The relevant section is §9.2.12 FunctionDeclarationInstantiation.

I must say that specification is rather hard to understand.

Yes it is, although it's written for engine implementors not for programmers. However, the explanatory note basically confirms your understanding of the optimisation

If the function’s formal parameters do not include any default value initializers then the body declarations are instantiated in the same Environment Record as the parameters. If default value parameter initializers exist, a second Environment Record is created for the body declarations.

Your examples basically desugar to

(function() {
  let a = arguments[0] !== undefined ? arguments[0] : b,
//                                                    ^ clearly a ReferenceError
      b = arguments[1] !== undefined ? arguments[1] : 1;
  {
  }
})();

(function() {
  let c = 1;
  return (function() {
    let a = arguments[0] !== undefined ? arguments[0] : c;
//                                                      ^ works as you'd think
    {
      return a === 1;
    }
  })();
})();

(function() {
  let a = 1;
  (function() {
    let a = arguments[0] !== undefined ? arguments[0] : a;
//                                                      ^ again clearly a ReferenceError
    {
    }
  })();
})();

(function() {
  let b = 1;
  (function() {
    let a = arguments[0] !== undefined ? arguments[0] : b,
//                                                      ^ still a ReferenceError
        b = arguments[1] !== undefined ? arguments[1] : 2;
    {
    }
  })();
})();

(function() {
  let a = arguments[0] !== undefined ? arguments[0] : () => b,
//                                                          ^ works indeed
      b = arguments[1] !== undefined ? arguments[1] : 2;
  {
    return a() === 2;
  }
})();

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...