这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战。
前言
ECMAScript 6.0 简称ES6 , 是 JavaScript 语言的新一代的标准,于在 2015 年 6 月发布,正式名称就是《ECMAScript 2015 标准》。一般情况,泛指, 5.1版以后的标准,涵盖了 ES2015、ES2016、ES2017、ES2018、ES2019、ES2020、ES2021 等等
我们一起来学习变量名解析问题。
先看两个例子
给君2分钟,思考一下,各自的输出结果是什么?
function arg(){
var arguments;
console.log(arguments);
}
arg(1,2,3);
function arg(arguments){
var arguments;
console.log(arguments);
}
arg(1,2,3);
答案:
- Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
- 1
这有什么规律吗?
名字来源
在JavaScript中,一个作用域(scope)中的名称(name)有以下四种:
1. 语言自身定义(Language-defined)
所有的作用域默认都会包含this和arguments。
2. 函数形参(Formal parameters)
函数有名字的形参会进入到函数体的作用域中。
3. 函数声明(Function decalrations)
通过function [name]() {}的形式。
4. 变量声明(Variable declarations)
通过var [name] 的形式。
当然,在ES6里面,多了 const 和 var的形式,基本也是属于第四种。
名字解析顺序
主要参考:JavaScript Scoping and Hoisting
一个名称进入一个作用域一共有四种方式。上面列出来的顺序,就是特名字的解析顺序。
总的来说,如果一个名称已经被 定义 了,他绝不会被另一个拥有不用属性的同名名称覆盖。
根据上面的顺序,函数声明比变量声明具有更高的优先级。仅仅是声明的部分会被忽略而已, 赋值操作依旧遵循该有的顺序。但是有下面几个例外:
- arguments是在形参之后,函数声明之前被声明。这就意味着名为arguments的形参会比内置的arguments具有更高的优先级,即使这个形参是undefined。 这个描述来自
按照这个推导: 形参 > arguments > 函数申明 > 变量申明
这就解释了的下面的输出结果:
// 形参 > arguments
function arg(arguments){
var arguments;
console.log(arguments);
}
arg(1,2,3); // 1
// arguments > 变量申明
function arg(){
var arguments;
console.log(arguments);
}
arg(1,2,3); //
// Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
但是这个结果有些意外
function arg(){
console.log(arguments);
function arguments(){}
}
arg(1,2,3);
// ƒ arguments(){}
咋眼一看不对啊, 其实 申明不等于赋值,而函数申明,直接会带有值,所以会进行覆盖。
形参,arguments, 变量申明,函数申明全部齐活, 其值依旧是 ƒ arguments(){}
function arg(arguments // 形参){
var arguments; // 变量申明
console.log(arguments);
function arguments(){} // 函数申明
}
-
任何地方试图使用this作为一个标识都会引起语法错误,这是一个好的特性。
-
如果有多个同名形参,那位于列表最后的形参拥有最高的优先级,即使它是undefined。
function args(num1, num2 , num1){
console.log("num1:", num1);
}
args(1) // num1: undefined
协议的描述
ES5.1 10.5 Declaration Binding Instantiation 也有提到顺序.
小结
今天你收获了吗?
引用
[翻译]JavaScript Scoping and Hoisting
JavaScript Scoping and Hoisting
Declaration Binding Instantiation
Name resolution order in JavaScript