Does a function expression have its own scope/lexical environment

强颜欢笑 提交于 2019-12-05 09:03:31

Yes, every function gets (§10.4.3) its own ExecutionContext when it is called (§13.2.1). That new context is initialised with a new LexicalEnvironment (created by NewDeclarativeEnvironment, §10.2.2.2), deriving from the [[Scope]] of the function - i.e. the LexicalEnvironment it was declared/"expressed" in (§13).

As @Pointy pointed out, the sentence you stumpled upon does not exhaustively list them: "…some [structure] such as…".

If a name is included in a FunctionExpression, that name becomes a read-only binding that shadows any outer declarations of the same name. But that binding may itself be shadowed by a formal parameter or local declaration within the function. Such a binding for the function name is only created for named FunctionExpressions and not for anonymous FunctionExpressions or FunctionDeclarations. The name binding for a FunctionDeclaration is created in the surrounding VariableEnvironment.

Here is a more detailed explantion referencing the ES5.1 spec:

There is more than one environment record associated with a function object. Whenever a function is called a new DeclarativeEnvironmentRecord is created to contain the local bindings of that particular function invocation. That record becomes both the VariableEnvironment and the initial LexicalEnvironment of the ExecutionContext that is created for that invocation. This is specified in section 10.4.3.

When this environment record is created its "outer environment" is set to the value of the [[Scope]] internal property of the function object that is being called. (line 5, 10.4.3) The outer environment provide the bindings for all non-local declarations. The [[Scope]] is set when a function object is created (see the semantics in section 13 and also 13.2). So, each distinct invocation of a specific function object has a different local environment but all invocations of that function share the same outer [[Scope]].

For most functions, the captured [[Scope]] is simply the LexicalEnvironment of the ExecutionContext that was active when the function is created. However FunctionExpressions that include an Identifier as the function name have an extra DeclarativeEnvironmentRecord insert at the head of its [[Scope]] chain. (see steps 1-3 of the third algorithm in section 13).

This extra environment record is used to capture the binding for the function name given in the FunctionExpression.

An instantiated function has a scope. It doesn't matter whether it was instantiated as part of a function declaration statement or a function instantiation expression.

(It's probably more correct to say that an instantiated function has a scope when it is called, and that every call produces a distinct scope.)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!