You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// 注意:函数声明也会被限制在它的语句块内,但是和let, const有区别// let {leta='a';}console.log(a)// ReferenceError: a is not defined// 函数声明,这里表现和有条件的创建函数类似foo('top outside...');// TypeError: foo is not a function{functionfoo(info){console.log(info)}foo('inside...');// inside...}foo('bottom outside...');// bottom outside...
块语句、声明和变量语句、空语句以及表达式语句
先看下以下代码,文末解惑:
1. block
求值
Block : { }
Block : { 语句列 }
语句列 : 语句列 语句列元素
BlockDeclarationInstantiation ( code, env )
遍历 d 的 BoundNames 中每个元素用 dn 表示
如果 d 是常量声明,
否则
如果 d 是 函数声明,Generator声明,异步函数声明,异步Generator声明
2. 声明和变量语句
let 和 const声明
求值
1. 词法声明 : LetOrConst 绑定列表 ;
2. 绑定列表 : 绑定列表 , 词法绑定
3. 词法绑定 : 绑定标识符
4. 词法绑定 : 绑定标识符 初始化器
5. 词法绑定 : 绑定模式 初始化器
3. 变量语句
求值
变量语句 : var 变量声明列表
变量声明列表 : 变量声明列表 , 变量声明
变量声明 : 绑定标识符
变量声明 : 绑定标识符 初始化器
变量声明 : 绑定模式 初始化器
4. 解构绑定模式
5. 空语句
6. 表达式语句
回顾开头代码
为什么var声明的变量和没有声明直接赋值的变量能绑定到window上,而let, const不行?
即使看了以上 var 以及 let/const 的规范相关定义,好像也无法得到这个问题的答案。虽然
var
在 运行时执行上下文 的 变量环境 中声明变量,而let
,const
在 运行时执行上下文 的 LexicalEnvironment 内声明变量,但是并没有说明我提出的这个问题。别急,看这里 GlobalDeclarationInstantiation(在Scripts and Modules那一章,太散了),它内部调用了 CreateGlobalVarBinding(vn, false),这个算法会把全局环境的
var
声明绑定到全局对象上!针对没有声明却赋值的变量在严格模式下会报错,见 C The Strict Mode of ECMAScript
找了整整两天啊,各种关键词都试过了,终于刚刚灵机一动,让我找到了未声明但赋值变量的蛛丝马迹!
这段代码其实是 赋值语句 啊!!!
先看它的求值算法,
age
既不是 对象字面量 也不是 数组字面量,最后会走 ? PutValue(lref, rval),而 PutValue 内部判断 lref 是不是 IsUnresolvableReference,事实上,的确是,因为根本没有这个变量!!!接下来,看下算法内部我需要关注的地方:
其实 Set 最终会调用对象的 [[Set]](GetReferencedName(V), W, globalObj),其本质 最终调用 OrdinarySetWithOwnDescriptor(o, GetReferencedName(V), W, globalObj, undefined),ownDesc 这里是 undefined,内部算法定义的 parent 也是 null,所以最终会返回 { [[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true } !!!
以上步骤才是隐式声明变量的关键,然后回到示例代码,对其赋值 21!
2020-03-15 补充
主要是迷惑了,以为考的是数组相关知识,实际上考的是 const 声明不能修改!!!
2020-03-21 补充
补充个经典面试题,输出什么:
2020-07-18 补充
这个算是 冗余声明(Redundant Declarations) 问题,今天看 《JavaScript 20 年》中文版 —— 迷惑行为与 Bug 发现的,以前没见过这个问题,即使看了规范和MDN也没意识到这个问题:
再看看下面代码:
同时需要注意
function
和var
的优先级,虽然都有变量提升功能,但是var
的优先级比function
高,这就造成了它们两同时声明同一种变量名时,function
声明会覆盖var
The text was updated successfully, but these errors were encountered: