一、语言基础
1、语法
- 区分大小写
- 标识符——就是变量、函数、属性或函数参数的名称。标识符第一个字符必须是一个字母、下划线(_)或美元符号($)
- 注释 //单行注释 /**_ 多行注释*_/
- 语句
- JavaScript语句以分号结尾,省略分号意味着由解析器确定语句在哪里结尾
2、关键字与保留字
ECMA-262描述了一组保留的关键字,这些关键字有特殊用途,比如表示控制语句的开始和结束,或者执行特定的操作。按照规定,保留的关键字不能用作标识符或属性名。
3、变量
ECMAScript变量是松散类型的,意思是变量可以用于保存任何类型的数据。每个变量只不过是一个用于保存任意值的命名占位符。
有3个关键字可以声明变量:var、const和let。
var
- 作用域:声明作用域是函数作用域
- 声明提升——字声明的变量会自动提升到函数作用域顶部
let
- 作用域:声明作用域是块级作用域
- 不会变量提升
- for循环中使用let声明可以解决之前使用var循环带来的变量渗透到循环体外部的问题
const
const的行为与let基本相同,唯一一个重要的区别是用它声明变量时必须同时初始化变量,且尝试修改const声明的变量会导致运行时错误。
- 作用域: 块级作用域
- const变量引用的是一个对象的话,可以修改对象内部的属性
声明风格和最佳实践
- 不使用var
限制自己只使用let和const有助于提升代码质量,因为变量有了明确的作用域、声明位置,以及不变的值。
- const优先,let次之
使用const声明可以让浏览器运行时强制保持变量不变,也可以让静态代码分析工具提前发现不合法的赋值操作。使用const声明可以让开发者更有信心地推断某些变量的值永远不会变,同时也能迅速发现因意外赋值导致的非预期行为。
4、数据类型
ECMAScript有6种简单数据类型(也称为原始类型),和一种复杂数据类型。在ECMAScript中不能定义自己的数据类型,所有值都可以用上述7种数据类型之一来表示。
- 简单数据类型:
Undefined
、Null
、Boolean
、Number
、String
和Symbol
。 - 复杂数据类型:
Object
(对象)。Object是一种无序键值对的集合。
typeof操作符
typeof
操作符用于确定任意变量的数据类型。
对一个值使用typeof
操作符会返回下列字符串之一:
undefined
表示值未定义;boolean
表示值为布尔值;string
表示值为字符串;number
表示值为数值;object
表示值为对象(而不是函数)或null;function
表示值为函数;symbol
表示值为符号
Undefined类型
Undefined
类型只有一个值,就是特殊值undefined
,表示未定义。当使用var或let声明了变量但没有初始化时,就相当于给变量赋予了undefined值:
Null类型
Null
类型同样只有一个值,即特殊值null。逻辑上讲,null值表示一个空对象指针,这也是给typeof
传一个null会返回"object"的原因:
💡在定义将来要保存对象值的变量时,建议使用null来初始化,不要使用其他值。这样,只要检查这个变量的值是不是null就可以知道这个变量是否在后来被重新赋予了一个对象的引用,
Boolean类型
Boolean(布尔值)类型是ECMAScript中使用最频繁的类型之一,有两个字面值:true和false。
虽然布尔值只有两个,但所有其他ECMAScript类型的值都有相应布尔值的等价形式(相当于强制类型转换)。
理解以上转换非常重要,因为像if等流控制语句会自动执行其他类型值到布尔值的转换
let message = "Hello world!";
if (message) {
console.log("Value is true");
}
// Value is true
Number类型
Number类型使用IEEE 754格式表示整数和浮点值(在某些语言中也叫双精度值)。
- 有一个特殊的数值叫NaN,意思是“不是数值”,用于表示本来要返回数值的操作失败了(而不是抛出错误)
- **isNaN()**函数,该函数接收一个参数,可以是任意数据类型,然后判断这个参数是否“不是数值”。
- Number() 转型函数,可用于任何数据类型。parseInt()和parseFloat()两个函数主要用于将字符串转换为数值。
String类型
String
(字符串)数据类型表示零或多个16位Unicode
字符序列。字符串可以使用双引号"
、单引号'
或反引号```标示。
**ES6新增了模板字面量,**使用反引号```来包括,在很多情况下可以极大的简化并提高代码的可读性:
- 字符串拼接,与之前使用单引号和+拼接不同,模板字符串可以使用包含
${expression}
表示占位符。
const people = {
name: 'Johnson',
job: 'Front-end'
}
const project = {
name: 'Dyniva'
}
// 之前拼接方式
let message = people.name + '(' + people.job + ')' + ' follow this project ' + project.name;
//ES6 模板字面量
let message = `${people.name}(${people.job}) follow this project ${project.name}`
- 所有插入的值都会使用
toString()
强制转型为字符串,而且任何JavaScript表达式都可以用于插值。 - 在插值表达式中可以调用函数和方法:
function capitalize(word) {
return `${ word[0].toUpperCase() }${ word.slice(1) }`;
}
console.log(`${ capitalize('hello') }, ${ capitalize('world') }!`); // Hello, World!
- 模板字面量可以保留换行字符,可以跨行定义字符串:
Symbol类型
Symbol
(符号)是ECMAScript 6新增的原始数据类型,。引入符号主要是为了解决对象属性使用唯一标识符,不会发生属性冲突的危险。
以下是Symbol的主要特点和用法:
- 基本语法:使用Symbol函数进行初始化,同时也可以指定一个字符串用于标识Symbol对象的用途。
let sym = Symbol();
console.log(typeof sym); // symbol
// 指定描述符
let symbol1 = Symbol('foo');
let symbol2 = Symbol('foo');
// 注意描述符仅用于表示标识符号,与symbol具体的值无关
console.log(symbol1 === symbol2); // false
- 作为属性键:
var obj = {};
var symbol = Symbol('foo');
obj[symbol] = 'bar';
console.log(obj[symbol]); // 'bar'
Symbol.for
创建可全局共享的symbol,
有时我们想要共用Symbol实例,这时可以使用Symbol.for
函数。
let fooGlobalSymbol = Symbol.for('foo'); // 创建新符号
let otherFooGlobalSymbol = Symbol.for('foo'); // 重用已有符号
console.log(fooGlobalSymbol === otherFooGlobalSymbol); // true
Symbol.for
函数对每个字符串执行幂等操作。第一次使用某个字符串调用时,它会检查全局运行时注册表,发现不存在对应的符号,于是就会生成一个新符号实例并添加到注册表中。后续使用相同字符串的调用同样会检查注册表,发现存在与该字符串对应的符号,然后就会返回该符号实例
Object类型
ECMAScript
中的对象其实就是一组数据和功能的集合。
类似Java中的java.lang.Object,ECMAScript中的Object也是派生其他对象的基类。Object类型的所有属性和方法在派生的对象上同样存在。
每个Object实例都有如下属性和方法。
constructor
:用于创建当前对象的函数。hasOwnProperty(_propertyName_)
:用于判断当前对象实例**(不是原型)**上是否存在给定的属性。isPrototypeOf(_object_)
:用于判断当前对象是否为另一个对象的原型。propertyIsEnumerable(_propertyName_)
:用于判断给定的属性是否可以使用for-in
语句枚举。与hasOwnProperty()
一样,属性名必须是字符串。toLocaleString()
:返回对象的字符串表示,该字符串反映对象所在的本地化执行环境。toString()
:返回对象的字符串表示。valueOf()
:返回对象对应的字符串、数值或布尔值表示。通常与toString()的返回值相同。
操作符
- 布尔操作符(逻辑非
!
、逻辑与&&
、逻辑或||
。)- 注意
**||**
操作符也常用于求默认值,与非布尔操作数一起使用,比如let a = defaultValue || 2
- 注意
- 相等操作符
- 等于(
==
)和不等于(!=
): 这两个操作符会先进行类型转换(通常称为强制类型转换)再确定操作数是否相等。 - 严格相等(
===
)和严格不相等(!==
) :这两个操作数在不转换的前提下判断是否相等。
- 等于(
- 条件操作符 (三元表达式)是ECMAScript中用途最为广泛的操作符之一,语法跟Java中一样
variable = boolean_expression ? true_value : false_value;
- 关系操作符(小于、大于、小于等于和大于等于)、
- 递增**/**递减操作符(++i --i)、一元加减乘除操作符、位操作符。
5、语句
IF语句
if语句是使用最频繁的语句之一,语法如下:
if (condition) statement1 else statement2
这里的条件(condition)可以是任何表达式,并且求值结果不一定是布尔值。ECMAScript会自动调用Boolean()函数将这个表达式的值转换为布尔值。
while语句
while语句是一种先测试循环语句,即先检测退出条件,再执行循环体内的代码。
while(expression) statement
for语句
for语句也是先测试语句,只不过增加了进入循环之前的初始化代码,以及循环执行后要执行的表达式
for (initialization; expression; post-loop-expression) statement
for -in语句
for-in语句是一种严格的迭代语句,用于枚举对象中的除Symbol以外的可枚举属性,
for-in总是得到对象的key或数组、字符串的下标。
for (property in expression) statement
// 循环显示了BOM对象window的所有属性
let arr = ['d', 's', 'r', 'c'];
for (const key in arr) {// 确保这个局部变量不被修改,推荐使用const
if (arr.hasOwnProperty(key)) {
console.log(key);
}
}
// 0
// 1
// 2
// 3
for -of语句
for-of语句是一种严格的迭代语句,用于遍历可迭代对象的元素
for-of总是得到对象的value或数组、字符串的值
//语法
for (property of expression) statement
//示例
for (const el of ['d', 's', 'r', 'c']) { // 确保这个局部变量不被修改,推荐使用const
console.log(el);
}
// d
// s
// r
// c
标签语句
break和continue语句
break
用于退出于立即退出循环,强制执行循环后的下一条语句。
而continue
语句也用于立即退出循环,但会再次从循环顶部开始执行。
switch 语句
switch (expression) {
case value1:
statement
break;
case value2:
statement
break;
case value3:
statement
break;
case value4:
statement
break;
default:
statement
}
6、函数
ECMAScript中的函数使用function
关键字声明,后跟一组参数,然后是函数体。
function functionName(arg0, arg1,...,argN) {
statements
}