目录
1.语法
1.1 区分大小写
1.2 标识符
1.3 注释
2.关键字与保留字
3.变量
3.1 var关键字
3.2 let声明
3.3 const声明
3.4声明风格及最佳实践
1.语法
1.1 区分大小写
ECMAScript中一切都区分大小写。无论是变量、函数名还是 *** 作符,都是区分大小写的。
举个例子说明:变量test和变量Test是两个不同的变量。
1.2 标识符什么是标识符?
在JS中所有的可以由我们自主命名的都可以称为是标识符。例如:变量名、函数名、属性名都属于标识符。
标识符命名需要遵守如下规则:
- 标识符可以由一或多个下列字符组成:
- 第一个字符必须是一个字符、下划线(_)或美元符号($)
- 剩下的其他字符可以是字母、下划线、美元符号或者数字、
- 标识符不能以数字开头
- 标识符不能使ES中的关键字或者保留字
- 按照惯例,ECMAScript标识符使用驼峰大小写形式,即第一个单词的首字母小写,后面每个单词的首字母大写,如:
firstSecond
myCar
doSomethingImportant
1.3 注释
ECMAScript采用C语言风格的注释,包括单行注释和块注释。单行注释以两个斜杠字符开头,如:
//单行注释
块注释以一个斜杠和一个星号(/*)开头,以它们的反向组合(*/)结尾,如:
/*
这是多行注释
*/
2.关键字与保留字
ECMA-262描述了一组保留的关键字,这些关键字有特殊用途,比如表示控制语句的开始和结束,或者执行特定的 *** 作。按照规定,保留的关键字不能用作标识符或属性名。ECMA-262第6版规定的所有关键字如下:
规范中也描述了一组未来的保留字,同样不能用作标识符或属性名。虽然保留字在语言中没有特定用途,但它们是保留给将来做关键字用的。
以下是ECMA-262第6版为将来保留的所有词汇。
3.变量3.1 var关键字注意:ECMAScript变量是松散类型的,意思是变量可以用于保存任何类型的数据。
定义一个变量,可以使用var(关键字) *** 作符,后跟变量名(即标识符):
var message
这其中有两点需要注意:
- 上面代码定义一个名为message的变量,它可以保存任何类型的值。
- 在没有初始化变量的情况下,变量会保存一个特殊值:undefined。
1 var声明作用域
var声明的变量的作用域只有两种:全局作用域、函数作用域。当var声明的变量在任何函数外面,则它的作用域是全局作用域;当var声明的变量在函数里面,则它的作用域是对应的函数作用域。
function test() {
var message = "hi"; // 局部变量
}
test();
console.log(message); // 出错!
在函数内部使用var定义局部变量,在函数调用时,给该变量赋值。调用之后随机被摧毁。在函数外部无法访问到局部变量。
不过,在函数内部定义变量时省略var *** 作符,可以创建一个全局变量。
function test() {
message="hi"; //全局变量
}
test();
console.log(message); // "hi"
去掉之前的var *** 作符之后,message就变成了全局变量。只要调用一次函数test(),就会定义这个变量,并且可以在函数外部访问到。
2 var声明提升
所谓的“提升”,可以简单理解为将所有变量声明都提到对应作用域的顶部。我们以还是局部变量为例:
下面的代码没有报错,这是因为使用var关键字声明的变量自动提升到了函数作用域的顶部。
function foo() {
console.log(age);
var age = 26;
}
foo(); // undefined
上面的代码等价于如下代码:
function foo() {
var age;
console.log(age);
age = 26;
}
foo(); // undefined
3.2 let声明
let声明的变量的作用域是它当前所处代码块,即它的作用域既可以是全局或则整个函数块,也可以是if、while、swith等用 { } 限定的代码块。
var允许在同一作用域中重复声明,而let不允许在同一作用域中重复声明,否则抛出异常。
var name;
var name;
let age;
let age; // SyntaxError;标识符age已经声明过了
1 暂时性死区
let与var的另一个重要的区别,就是let声明的变量不会在作用域中被提升。
// name会被提升
console.log(name); // undefined
var name = 'Matt';
// age不会被提升
console.log(age); // ReferenceError:age没有定义
let age = 26;
在解析代码时,JavaScript引擎也会注意出现在块后面的let声明,只不过在此之前不能以任何方式来引用未声明的变量。在let声明之前的执行瞬间被称为“暂时性死区”(temporal dead zone),在此阶段引用任何后面才声明的变量都会抛出ReferenceError。
2 全局声明
与var关键字不同,使用let在全局作用域中声明的变量不会成为window对象的属性(var声明的变量则会)。
var name = 'Matt';
console.log(window.name); // 'Matt'
let age = 26;
console.log(window.age); // undefine
不过,let声明仍然是在全局作用域中发生的,相应变量会在页面的生命周期内存续。因此,为了避免SyntaxError,必须确保页面不会重复声明同一个变量。
3.3 const声明const的行为与let基本相同,唯一一个重要的区别是用它声明变量时必须同时初始化变量,且尝试修改const声明的变量会导致运行时错误。
const age = 26;
age = 36; // TypeError:给常量赋值
// const也不允许重复声明
const name = 'Matt';
const name = 'Nicholas'; // SyntaxError
// const声明的作用域也是块
const name = 'Matt';
if (true) {
const name = 'Nicholas';
}
console.log(name); // Matt
const声明的限制只适用于它指向的变量的引用。换句话说,如果const变量引用的是一个对象,那么修改这个对象内部的属性并不违反const的限制。
const person = {};
person.name = 'Matt'; // ok
JavaScript引擎会为for循环中的let声明分别创建独立的变量实例,虽然const变量跟let变量很相似,但是不能用const来声明迭代变量(因为迭代变量会自增):
for (const i = 0; i < 10; ++i) {} // TypeError:给常量赋值
不过,如果你只想用const声明一个不会被修改的for循环变量,那也是可以的。也就是说,每次迭代只是创建一个新变量。这对for-of和for-in循环特别有意义:
let i = 0;
for (const j = 7; i < 5; ++i) {
console.log(j);
}
// 7, 7, 7, 7, 7
for (const key in {a: 1, b: 2}) {
console.log(key);
}
// a, b
for (const value of [1,2,3,4,5]) {
console.log(value);
}
// 1, 2, 3, 4, 5
3.4声明风格及最佳实践
ECMAScript 6增加let和const从客观上为这门语言更精确地声明作用域和语义提供了更好的支持。行为怪异的var所造成的各种问题,已经让JavaScript社区为之苦恼了很多年。随着这两个新关键字的出现,新的有助于提升代码质量的最佳实践也逐渐显现。
1.不使用var
有了let和const,大多数开发者会发现自己不再需要var了。限制自己只使用let和const有助于提升代码质量,因为变量有了明确的作用域、声明位置,以及不变的值。
2.const优先,let次之
使用const声明可以让浏览器运行时强制保持变量不变,也可以让静态代码分析工具提前发现不合法的赋值 *** 作。因此,很多开发者认为应该优先使用const来声明变量,只在提前知道未来会有修改时,再使用let。这样可以让开发者更有信心地推断某些变量的值永远不会变,同时也能迅速发现因意外赋值导致的非预期行为。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)