大家好,我是Ysh,谨以此系列文章献给正在初中级阶段的开发兄弟们,愿大家年年高升无寒冬。
创作不易,还请兄弟们多多点赞、收藏、关注 三联走起~
前言
任何高级语言的核心,通常由语法
、操作符
、数据类型
、流程控制语句
、内置功能
、保留字``关键字
、这七项构成,我们通常是在掌握了这些语言核心项的基础上进行需求开发(构建解决方案),大部分的框架也都是根据语言的这几项进行的功能封装,因此,了解并掌握这些核心项是至关重要的。
本篇文章将对这七项语言核心进行阐明,使大家有一个基本概念。
ECMAScript:JS的核心
JavaScript 由 Brendan Eich 在网景公司任职,因当时需求于1995年5月开发,最初,这种语言被称为Mocha,然后改名为LiveScript,最终在与Sun Microsystems合作后命名为JavaScript(蹭Java热度)。
JavaScript一经推出火爆互联网界,但由于没有统一的规范制定,在未来两年发展中(1995~1997),JavaScript在多个浏览器中的实现存在差异,导致了兼容性问题。
为了规范和标准化JavaScript,网景公司将JavaScript提交给欧洲计算机制造商协会(ECMA)。1997年,ECMA发布了ECMAScript标准的第一版(ECMA-262)。
注意:ECMAScript是一种语言规范,任何语言都可以根据该规范实现,JavaScript实现了ECMAScript语法规范,但JS除了ECMAScript规范中定义的之外还有其他功能:DOM、BOM,如图所示:
语法
JavaScript的语法很大程度上借鉴了C语言的语法,但相对更宽松。
严格区分大小写
JavaScript是严格区分大小写的,例如:变量A与变量a 他们在JS中是两个变量。
标识符
标识符
其实就是变量、函数、函数参数、对象的名称,JS定义标识符的规范如下:
-
标识符必须为字母、下划线()或美元符号(),不能用数字开头
-
标识符推荐使用小驼峰命名法命名,如:myName、myAge等
-
关键字、保留字、true、false与null不能用作标识符
关键字:指的是语言中已经使用的名字,如:Object,function,基本类型Boolean的true、false 保留字:指的是语言中没有使用,但以后可能使用的名字。
注释
JavaScript采用C语言风格的注释写法,分为单行注释与多行注释:
//这是单行注释,注释了这一行的内容
/* 这是多行注释
* 又叫块注释
* 顾名思义会注释被引号星包含起来的一整块地方
*/
语句
JavaScript中的语句,分为单行语句与多行语句
//如声明一个变量a,单行语句应当以分号结尾
let a = 12;
//多行语句可以合并用{}合并在一起,这种合并到一起的代码又叫代码块
{
console.log(123);//在浏览器上打印123
console.log(123);//在浏览器上打印123
}
变量
在JavaScript中,变量是用于存储数据的容器
,理解变量的 声明 、 作用域 、 提升 以及 不同类型的变量 是掌握JavaScript语法的关键点
之前我们提到过,JS的语法是宽松的,这一点在变量上有所体现,也就是说,JS的变量可以保存任何类型的数据。JS中有三个关键字用来声明变量,分别为var
、let
、const
。
image.png
var name = ‘张三’; //es5声明变量关键字
let age = 21; // es6新增变量关键字
const sex = '男'; // es6新增常量关键字,声明并赋值后不可更改
var
关键字
var
是ES5及之前版本中用于声明变量的关键字。var
声明的变量具有函数作用域或全局作用域,并且变量声明会被提升(hoisting)到作用域的顶部。
注意: 在代码块中生命的变量只会在代码块中生效,且随着代码块执行完成后销毁内存空间占用而消失,在代码块外面调用会报错:
Uncaught ReferenceError
var x = 10;
console.log(x); // 10
function test() {
var y = 20;
console.log(y); // 20
}
test();
// console.log(y); // Uncaught ReferenceError: y is not defined
变量提升(Hoisting)
var
声明的变量会被提升到其作用域的顶部,只声明没复制时会有默认值undefined,但初始化赋值不会被提升。
console.log(a); // undefined
var a = 5;
console.log(a); // 5
上述代码等价于:
var a;
console.log(a); // undefined
a = 5;
console.log(a); // 5
let
let
是ES6引入的关键字,用于声明块作用域(block scope)变量。let
声明的变量不会被提升。
注意: 在let声明中,同样是在代码块中生命的变量只会在代码块中生效,且随着代码块执行完成后销毁内存空间占用而消失,在代码块外面调用会报错:
Uncaught ReferenceError
let x = 10;
console.log(x); // 10
{
let y = 20;
console.log(y); // 20
}
// console.log(y); // Uncaught ReferenceError: y is not defined
重复声明
在同一作用域中,使用let
声明的变量不能重复声明。
let z = 30;
// let z = 40; // Uncaught SyntaxError: Identifier 'z' has already been declared
const
关键字
const
也是ES6引入的关键字,用于声明常量。常量是块作用域变量,声明时必须初始化,且值不能重新赋值。
const x = 10;
console.log(x); // 10
// x = 20; // Uncaught TypeError: Assignment to constant variable
对象和数组的常量
const
声明的对象和数组的引用不能改变,但其内容是可变的。
const obj = { name: "Alice" };
obj.name = "Bob";
console.log(obj.name); // "Bob"
const arr = [1, 2, 3];
arr.push(4);
console.log(arr); // [1, 2, 3, 4]
变量作用域
变量的作用域决定了变量在何处可访问。在JavaScript中,变量作用域分为全局作用域、函数作用域和块作用域。
全局作用域
在全局作用域中声明的变量可以在代码的任何地方访问。全局变量可以通过window
对象(在浏览器中)或global
对象(在Node.js中)访问。
var globalVar = "I am global";
function test() {
console.log(globalVar); // "I am global"
}
test();
函数作用域
函数作用域中的变量只能在该函数内部访问。var
声明的变量具有函数作用域。
function test() {
var functionVar = "I am inside a function";
console.log(functionVar); // "I am inside a function"
}
test();
// console.log(functionVar); // Uncaught ReferenceError: functionVar is not defined
块作用域
块作用域是由一对花括号({}
)定义的。let
和const
声明的变量具有块作用域。
{
let blockVar = "I am inside a block";
console.log(blockVar); // "I am inside a block"
}
// console.log(blockVar); // Uncaught ReferenceError: blockVar is not defined
变量提升(Hoisting)
变量提升是指在代码执行前,变量声明会被提升到其作用域的顶部,但初始化不会被提升。var
声明的变量会被提升,而let
和const
声明的变量不会被提升。
console.log(a); // undefined
var a = 5;
console.log(a); // 5
// console.log(b); // Uncaught ReferenceError: Cannot access 'b' before initialization
let b = 10;
变量的生命周期
变量的生命周期指的是变量从声明到销毁的过程。
var
变量的生命周期
-
声明:当进入其作用域时。
-
初始化:当代码执行到变量声明时。
-
销毁:当作用域结束时。
let
和 const
变量的生命周期
-
声明:当进入其块作用域时。
-
初始化:当代码执行到变量声明时。
-
销毁:当块作用域结束时。
数据类型
JavaScript作为一种动态语言,支持多种数据类型。这些数据类型分为基本数据类型(原始类型)和复杂数据类型(引用类型),如下图所示:
image.png
基本数据类型(Primitive Types)
JavaScript的基本数据类型在当前版本下是固定不变的,这些类型包括:
1. Number
Number
类型表示数字,包括整数和浮点数。JavaScript使用IEEE 754双精度64位浮点数格式来表示数字。
let integer = 42; // 整数
let float = 3.14; // 浮点数
Number
类型也包含一些特殊值:
-
Infinity
:表示无穷大。 -
-Infinity
:表示负无穷大。 -
NaN
(Not-a-Number):表示非数字值,通常是非法数学操作的结果。
console.log(1 / 0); // Infinity
console.log(-1 / 0); // -Infinity
console.log("hello" / 2); // NaN
2. String
String
类型表示文本数据。字符串是不可变的,可以使用单引号、双引号或反引号(模板字符串)定义。
let singleQuote = 'Hello, world!';
let doubleQuote = "Hello, world!";
let templateLiteral = `Hello, ${name}!`; // 模板字符串支持插值和多行字符串
3. Boolean
Boolean
类型表示布尔值,只有两个取值:true
和false
。
let isTrue = true;
let isFalse = false;
4. Undefined
Undefined
类型表示未定义的值。当声明一个变量但未赋值时,该变量的值为undefined
。
let x;
console.log(x); // undefined
5. Null
Null
类型表示空值,即不存在的引用。与undefined
不同,null
是一个表示“空”或“无”的明确值。
let y = null;
console.log(y); // null
6. Symbol
Symbol
类型是ES6引入的一种新的基本数据类型,表示唯一且不可变的值。它通常用于对象属性的唯一标识符。
let symbol1 = Symbol('description');
let symbol2 = Symbol('description');
console.log(symbol1 === symbol2); // false
7. BigInt
BigInt
类型也是ES6引入的一种新的基本数据类型,用于表示任意精度的整数。它通过在整数后添加n
来创建。
let bigInt = 1234567890123456789012345678901234567890n;
复杂数据类型(Reference Types)
复杂数据类型是可以扩展的对象类型,值是可变的。主要包括:
1. Object
Object
类型是JavaScript中最重要的复杂数据类型。对象是键值对的集合,键是字符串(也可以是Symbol
),值可以是任何类型。
let person = {
name: "John",
age: 30,
greet: function() {
console.log("Hello!");
}
};
2. Array
Array
类型是用于存储有序数据集合的特殊对象。数组的元素可以是任何类型,数组长度是动态变化的。
let array = [1, 2, 3, "four", { name: "five" }];
console.log(array[0]); // 1
console.log(array[3]); // "four"
3. Function
Function
类型是JavaScript中的一等公民,即函数是对象,可以赋值给变量、作为参数传递给其他函数或从其他函数返回。
function greet(name) {
return `Hello, ${name}!`;
}
let sayHello = greet;
console.log(sayHello("Alice")); // "Hello, Alice!"
4. Date
Date
类型用于处理日期和时间。JavaScript使用Date
对象提供日期和时间的相关操作。
let now = new Date();
console.log(now); // 当前日期和时间
5. RegExp
RegExp
类型用于表示正则表达式,提供字符串模式匹配功能。
let pattern = /hello/;
console.log(pattern.test("hello world")); // true
6. Map
和 Set
Map
类型是键值对的集合,键和值可以是任何类型。Set
类型是值的集合,所有值都是唯一的。
let map = new Map();
map.set("key", "value");
console.log(map.get("key")); // "value"
let set = new Set();
set.add(1);
set.add(2);
set.add(2); // 重复值不会添加
console.log(set.size); // 2
7. WeakMap
和 WeakSet
WeakMap
和WeakSet
类似于Map
和Set
,但其键和值是弱引用,可以被垃圾回收机制回收,不会阻止对象被回收。
let weakMap = new WeakMap();
let obj = {};
weakMap.set(obj, "value");
console.log(weakMap.get(obj)); // "value"
动态类型与类型转换
JavaScript是动态类型语言,变量的类型可以在运行时改变。类型转换分为显式转换和隐式转换。
显式转换
显式转换是通过使用内置函数或运算符进行的。
let num = "123";
let number = Number(num); // 字符串转换为数字
let str = String(number); // 数字转换为字符串
let bool = Boolean(number); // 非零数字转换为布尔值true
隐式转换
隐式转换是JavaScript在运行时自动进行的类型转换。
let result = "5" - 3; // 2,字符串"5"被隐式转换为数字
let concat = "5" + 3; // "53",数字3被隐式转换为字符串
操作符
在JavaScript中,操作符是JavaScript中执行各种操作的基本单位,是对值进行操作的符号或关键字,且可以对一个或多个值进行操作,并返回结果。
基本算术操作符
加法操作符(+
)
用于两个数值相加或连接两个字符串。
let sum = 5 + 3; // 8
let concatenatedString = "Hello, " + "world!"; // "Hello, world!"
减法操作符(-
)
用于两个数值相减。
let difference = 10 - 4; // 6
乘法操作符(*
)
用于两个数值相乘。
let product = 6 * 7; // 42
除法操作符(/
)
用于两个数值相除。
let quotient = 20 / 4; // 5
取模操作符(%
)
用于计算两个数值相除的余数。
let remainder = 10 % 3; // 1
指数操作符(**
)
用于计算第一个操作数的第二个操作数次幂。
let power = 2 ** 3; // 8
赋值操作符
简单赋值操作符(=
)
将右侧的值赋给左侧的变量。
let x = 10;
复合赋值操作符
用于将算术操作和赋值操作结合。
let y = 5;
y += 3; // 等价于 y = y + 3; 结果是 8
y -= 2; // 等价于 y = y - 2; 结果是 6
y *= 4; // 等价于 y = y * 4; 结果是 24
y /= 3; // 等价于 y = y / 3; 结果是 8
y %= 5; // 等价于 y = y % 5; 结果是 3
y **= 2; // 等价于 y = y ** 2; 结果是 9
比较操作符
相等操作符(==
)
比较两个值是否相等,进行类型转换。
console.log(5 == "5"); // true
全等操作符(===
)
比较两个值是否全等,不进行类型转换。
console.log(5 === "5"); // false
不相等操作符(!=
)
比较两个值是否不相等,进行类型转换。
console.log(5 != "5"); // false
不全等操作符(!==
)
比较两个值是否不全等,不进行类型转换。
console.log(5 !== "5"); // true
大于操作符(>
)
比较左侧值是否大于右侧值。
console.log(10 > 5); // true
大于或等于操作符(>=
)
比较左侧值是否大于或等于右侧值。
console.log(10 >= 10); // true
小于操作符(<
)
比较左侧值是否小于右侧值。
console.log(5 < 10); // true
小于或等于操作符(<=
)
比较左侧值是否小于或等于右侧值。
console.log(10 <= 10); // true
逻辑操作符
逻辑与操作符(&&
)
用于两个操作数都为真时,返回真,否则返回假。
console.log(true && false); // false
console.log(true && true); // true
逻辑或操作符(||
)
用于两个操作数中至少有一个为真时,返回真,否则返回假。
console.log(true || false); // true
console.log(false || false); // false
逻辑非操作符(!
)
用于取反操作数的布尔值。
console.log(!true); // false
console.log(!false); // true
位操作符
位操作符对其操作数的二进制表示形式进行操作。
按位与操作符(&
)
对两个数值的每一位执行与(AND)操作。
console.log(5 & 1); // 1 (0101 & 0001 = 0001)
按位或操作符(|
)
对两个数值的每一位执行或(OR)操作。
console.log(5 | 1); // 5 (0101 | 0001 = 0101)
按位异或操作符(^
)
对两个数值的每一位执行异或(XOR)操作。
console.log(5 ^ 1); // 4 (0101 ^ 0001 = 0100)
按位非操作符(~
)
对数值的每一位执行非(NOT)操作。
console.log(~5); // -6 (~0101 = 1010)
左移操作符(<<
)
将一个数值的所有位向左移动指定的位数。
console.log(5 << 1); // 10 (0101 << 1 = 1010)
右移操作符(>>
)
将一个数值的所有位向右移动指定的位数。
console.log(5 >> 1); // 2 (0101 >> 1 = 0010)
无符号右移操作符(>>>
)
将一个数值的所有位向右移动指定的位数,并用零填充左侧的位。
console.log(5 >>> 1); // 2 (0101 >>> 1 = 0010)
其他操作符
三元操作符(? :
)
根据条件表达式的值来返回一个值。
let age = 20;
let allowed = (age >= 18) ? "Yes" : "No";
console.log(allowed); // "Yes"
逗号操作符(,
)
在一行代码中执行多个操作,并返回最后一个操作的结果。
let x = (1 + 2, 3 + 4);
console.log(x); // 7
typeof 操作符
返回操作数的数据类型。
console.log(typeof 42); // "number"
console.log(typeof "hello"); // "string"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof null); // "object"(这是一个语言的设计缺陷)
console.log(typeof {}); // "object"
console.log(typeof function(){}); // "function"
delete 操作符
用于删除对象的属性。
let obj = { name: "Alice", age: 25 };
delete obj.age;
console.log(obj); // { name: "Alice" }
in 操作符
用于检查对象是否包含特定的属性。
let obj = { name: "Alice", age: 25 };
console.log("name" in obj); // true
console.log("gender" in obj); // false
instanceof 操作符
用于检查对象是否是某个构造函数的实例。
let arr = [];
console.log(arr instanceof Array); // true
console.log(arr instanceof Object); // true
语句
在JavaScript中,语句是构成程序的基本单位。每个语句执行特定的操作,并以分号(;
)结束。
变量声明语句
var
语句
用于声明一个变量。
var x = 10;
let
语句
用于声明一个块作用域的变量。
let y = 20;
const
语句
用于声明一个块作用域的常量。
const z = 30;
表达式语句
表达式语句是以表达式开头的语句。它们通常用于赋值、调用函数或执行算术运算。
x = y + z;
console.log(x);
条件语句
条件语句根据表达式的值来执行不同的代码块。
if
语句
根据条件表达式的值执行代码块。
if (x > 10) {
console.log("x is greater than 10");
}
if...else
语句
根据条件表达式的值执行不同的代码块。
if (x > 10) {
console.log("x is greater than 10");
} else {
console.log("x is less than or equal to 10");
}
if...else if...else
语句
检查多个条件。
if (x > 10) {
console.log("x is greater than 10");
} else if (x < 5) {
console.log("x is less than 5");
} else {
console.log("x is between 5 and 10");
}
switch
语句
根据表达式的值执行多个代码块中的一个。
switch (x) {
case 1:
console.log("x is 1");
break;
case 2:
console.log("x is 2");
break;
default:
console.log("x is neither 1 nor 2");
}
循环语句
循环语句用于重复执行代码块。
for
语句
用于固定次数的循环。
for (let i = 0; i < 5; i++) {
console.log(i);
}
while
语句
在条件表达式为真时执行代码块。
let i = 0;
while (i < 5) {
console.log(i);
i++;
}
do...while
语句
先执行代码块,再检查条件表达式。
let i = 0;
do {
console.log(i);
i++;
} while (i < 5);
for...in
语句
用于遍历对象的可枚举属性。
let obj = { a: 1, b: 2, c: 3 };
for (let key in obj) {
console.log(key, obj[key]);
}
for...of
语句
用于遍历可迭代对象(如数组、字符串、Map和Set)。
let arr = [1, 2, 3];
for (let value of arr) {
console.log(value);
}
跳转语句
跳转语句用于改变代码的执行顺序。
break
语句
终止当前循环或代码块,并跳出该循环或代码块。
for (let i = 0; i < 5; i++) {
if (i === 3) {
break;
}
console.log(i);
}
continue
语句
终止当前循环的当前迭代,并继续执行下一个迭代。
for (let i = 0; i < 5; i++) {
if (i === 3) {
continue;
}
console.log(i);
}
return
语句
终止当前函数的执行,并返回一个值。
function sum(a, b) {
return a + b;
}
console.log(sum(2, 3)); // 5
throw
语句
抛出一个用户自定义的异常。
function checkAge(age) {
if (age < 18) {
throw new Error("You must be at least 18 years old.");
}
return "Access granted";
}
try...catch
语句
用于处理异常。try
块包含可能抛出异常的代码,catch
块包含处理异常的代码。
try {
let result = checkAge(16);
console.log(result);
} catch (error) {
console.log(error.message);
}
其他语句
debugger
语句
用于停止代码执行,并调用调试工具,使用调试工具手动执行后续代码。
function debugExample() {
debugger;
console.log("Debugging");
}
debugExample();
with
语句 (已弃用)
用于将代码的作用域设置为特定的对象(不推荐使用,因为可能导致代码难以理解和调试)。
let obj = { a: 1, b: 2 };
with (obj) {
console.log(a); // 1
console.log(b); // 2
}
空语句
空语句用于创建没有任何执行语句的代码块。
for (let i = 0; i < 5; i++) {
; // 空语句
}
标签语句
标签语句用于标识代码块,以便与break
或continue
语句一起使用。
outerLoop: for (let i = 0; i < 5; i++) {
for (let j = 0; j < 5; j++) {
if (j === 3) {
break outerLoop;
}
console.log(i, j);
}
}
函数
函数是JavaScript中强大的编程工具,将可重复使用的代码块进行封装,函数不仅可以执行特定任务,还可以返回值。
函数声明
函数声明使用function
关键字,并且有一个可选的名称。
function greet(name) {
return `Hello, ${name}!`;
}
函数可以通过名称调用,并传递参数:
let message = greet("Alice");
console.log(message); // "Hello, Alice!"
函数表达式
函数表达式是将函数赋值给变量或常量。函数表达式可以是匿名的,也可以是命名的。
// 匿名函数表达式
let greet = function(name) {
return `Hello, ${name}!`;
};
// 命名函数表达式
let greet = function greetFunction(name) {
return `Hello, ${name}!`;
};
箭头函数
箭头函数是ES6引入的一种简洁的函数表达方式(语法糖),它使用=>
语法,使其语法更简短,但没有自己的this
指向。
let greet = (name) => {
return `Hello, ${name}!`;
};
// 如果函数体只有一个表达式,可以省略花括号和`return`关键字
let greet = (name) => `Hello, ${name}!`;
函数参数
函数可以接受参数,也可以有默认参数值。
function greet(name = "Guest") {
return `Hello, ${name}!`;
}
console.log(greet()); // "Hello, Guest!"
console.log(greet("Alice")); // "Hello, Alice!"
Rest参数
Rest参数允许函数接受不定数量的参数,并将它们作为数组传入。
function sum(...numbers) {
return numbers.reduce((total, number) => total + number, 0);
}
console.log(sum(1, 2, 3)); // 6
console.log(sum(4, 5)); // 9
Arguments对象
在非箭头函数中,arguments
对象会包含传递给函数的所有参数。它类似数组,但不是数组实例。
function sum() {
let total = 0;
for (let i = 0; i < arguments.length; i++) {
total += arguments[i];
}
return total;
}
console.log(sum(1, 2, 3)); // 6
console.log(sum(4, 5)); // 9
函数返回值
函数可以返回值,使用return
语句。如果没有return
语句,函数会返回undefined
。
function multiply(a, b) {
return a * b;
}
console.log(multiply(2, 3)); // 6
function noReturn() {
let x = 10;
}
console.log(noReturn()); // undefined
函数作用域和闭包
作用域
函数作用域指的是变量在函数内的可见性。在函数内部声明的变量在函数外部不可见。
function test() {
let x = 10;
console.log(x); // 10
}
test();
// console.log(x); // Uncaught ReferenceError: x is not defined
闭包
闭包是指函数可以访问其词法作用域中的变量,即使函数在其词法作用域之外执行。
function outer() {
let outerVar = "I'm outside!";
function inner() {
console.log(outerVar); // "I'm outside!"
}
return inner;
}
let innerFunc = outer();
innerFunc();
高阶函数
高阶函数是指可以接受一个或多个函数作为参数,或返回一个函数作为结果的函数。
接受函数作为参数
function applyOperation(a, b, operation) {
return operation(a, b);
}
function add(x, y) {
return x + y;
}
function multiply(x, y) {
return x * y;
}
console.log(applyOperation(5, 3, add)); // 8
console.log(applyOperation(5, 3, multiply)); // 15
返回一个函数
function createGreeting(greeting) {
return function(name) {
return `${greeting}, ${name}!`;
};
}
let sayHello = createGreeting("Hello");
let sayHi = createGreeting("Hi");
console.log(sayHello("Alice")); // "Hello, Alice!"
console.log(sayHi("Bob")); // "Hi, Bob!"
自调用函数(IIFE)
自调用函数(Immediately Invoked Function Expression,IIFE)是一种定义后立即执行的函数。
(function() {
console.log("This is an IIFE");
})();
函数递归
递归是函数调用自身的技术。它用于解决需要重复分解问题的场景。
function factorial(n) {
if (n === 0) {
return 1;
}
return n * factorial(n - 1);
}
console.log(factorial(5)); // 120
函数作为对象的方法
函数可以作为对象的方法,this
关键字在方法中指向调用该方法的对象。
let person = {
name: "Alice",
greet: function() {
return `Hello, ${this.name}!`;
}
};
console.log(person.greet()); // "Hello, Alice!"
异步函数
回调函数
回调函数是作为参数传递给另一个函数,并在特定事件发生时调用的函数。
function fetchData(callback) {
setTimeout(() => {
let data = "Data fetched";
callback(data);
}, 1000);
}
fetchData(function(data) {
console.log(data); // "Data fetched"
});
Promise
Promise是ES6引入的用于处理异步操作的对象。
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Data fetched");
}, 1000);
});
promise.then(data => {
console.log(data); // "Data fetched"
}).catch(error => {
console.error(error);
});
Async/Await
Async/Await是ES8引入的用于处理Promise的语法糖,使异步代码看起来像同步代码。
async function fetchData() {
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Data fetched");
}, 1000);
});
let data = await promise;
console.log(data); // "Data fetched"
}
fetchData();
关键字
关键字是JavaScript中具有预定义功能的词汇,它们用于执行特定操作或定义语言结构。以下是JavaScript中的关键字及其作用:
控制结构关键字
-
if
:用于条件语句。 -
else
:用于条件语句的替代分支。 -
switch
:用于多分支条件语句。 -
case
:用于定义switch
语句中的一个分支。 -
default
:用于定义switch
语句中的默认分支。
循环关键字
-
for
:用于循环。 -
while
:用于循环。 -
do
:用于do...while
循环。 -
break
:用于跳出循环或switch
语句。 -
continue
:用于跳过循环的当前迭代。
函数关键字
-
function
:用于定义函数。 -
return
:用于从函数中返回值。
变量声明关键字
-
var
:用于声明变量(具有函数作用域)。 -
let
:用于声明块作用域变量(ES6引入)。 -
const
:用于声明块作用域常量(ES6引入)。
作用域和上下文关键字
-
this
:用于引用当前对象。 -
new
:用于创建对象的实例。 -
delete
:用于删除对象的属性。 -
typeof
:用于确定变量的数据类型。 -
instanceof
:用于测试对象是否为某构造函数的实例。 -
in
:用于判断属性是否在对象中。
异常处理关键字
-
try
:用于定义一个可能抛出异常的代码块。 -
catch
:用于捕获并处理异常。 -
finally
:用于定义一个总会执行的代码块(不论是否抛出异常)。 -
throw
:用于抛出一个用户自定义的异常。
类与模块关键字(ES6引入)
-
class
:用于定义类。 -
extends
:用于继承类。 -
super
:用于调用父类的构造函数或方法。 -
import
:用于导入模块。 -
export
:用于导出模块。
其他关键字
-
void
:用于指定表达式不返回值。 -
yield
:用于生成器函数。 -
await
:用于异步函数。 -
async
:用于定义异步函数。
保留字
保留字是被JavaScript语言保留,但当前未作为关键字使用的词汇。这些词汇在未来版本中可能会被用作关键字,因此不能用作标识符。以下是JavaScript中的保留字:
未来保留字(包括严格模式下)
-
enum
:用于定义枚举(未来可能引入)。 -
implements
:用于接口实现(未来可能引入)。 -
interface
:用于定义接口(未来可能引入)。 -
package
:用于定义包(未来可能引入)。 -
private
:用于定义私有属性或方法(未来可能引入)。 -
protected
:用于定义受保护的属性或方法(未来可能引入)。 -
public
:用于定义公共属性或方法(未来可能引入)。 -
static
:用于定义静态属性或方法(未来可能引入)。
其他保留字
这些词汇虽然目前不是关键字,但在严格模式(strict mode)下也不能作为标识符使用:
-
await
-
yield
已弃用或仅在特定环境中保留
某些保留字在早期版本中使用,但在现代JavaScript中已经弃用或仅在特定环境下保留:
-
abstract
-
boolean
-
byte
-
char
-
double
-
final
-
float
-
goto
-
int
-
long
-
native
-
short
-
synchronized
-
transient
-
volatile
总结
前言
任何高级语言的核心通常由以下七项构成:语法
、操作符
、数据类型
、流程控制语句
、内置功能
、保留字
和关键字
。我们通常是在掌握这些语言核心项的基础上进行需求开发(构建解决方案)。大部分框架也基于这些核心项进行功能封装,因此,了解并掌握这些核心项是至关重要的。本篇文章将对这七项语言核心进行阐明,使大家有一个基本概念。
ECMAScript:JS的核心
JavaScript由Brendan Eich在网景公司开发,最初称为Mocha,后改名为LiveScript,最终在与Sun Microsystems合作后命名为JavaScript。由于缺乏统一规范,JavaScript在早期发展中出现了兼容性问题。为了解决这个问题,网景公司将JavaScript提交给欧洲计算机制造商协会(ECMA),1997年发布了ECMAScript标准第一版(ECMA-262)。
语法
JavaScript的语法借鉴了C语言,但相对更宽松。其主要特点包括:
-
严格区分大小写:如变量
A
和变量a
是不同的。 -
标识符:必须以字母、下划线或美元符号开头,不能用数字开头,推荐使用小驼峰命名法。
-
注释:单行注释用
//
,多行注释用/* ... */
。 -
语句:以分号结束,多行语句可以用
{}
包裹。
变量
JavaScript的变量可以保存任何类型的数据,有三个关键字用于声明变量:var
、let
和const
。
-
var
:函数作用域或全局作用域,声明会被提升。 -
let
:块作用域,不会被提升,不能重复声明。 -
const
:块作用域,声明时必须初始化,且值不能重新赋值。对象和数组的引用不能改变,但内容是可变的。
数据类型
JavaScript支持基本数据类型(原始类型)和复杂数据类型(引用类型)。
-
基本数据类型:
Number
、String
、Boolean
、Undefined
、Null
、Symbol
、BigInt
。 -
复杂数据类型:
Object
、Array
、Function
、Date
、RegExp
、Map
、Set
、WeakMap
、WeakSet
。
操作符
JavaScript中的操作符用于对值进行操作,包括基本算术操作符、赋值操作符、比较操作符、逻辑操作符、位操作符和其他操作符。
-
算术操作符:
+
、-
、*
、/
、%
、**
。 -
赋值操作符:
=
、+=
、-=
、*=
、/=
、%=
、**=
。 -
比较操作符:
==
、===
、!=
、!==
、>
、>=
、<
、<=
。 -
逻辑操作符:
&&
、||
、!
。 -
位操作符:
&
、|
、^
、~
、<<
、>>
、>>>
。 -
其他操作符:
?:
、,
、typeof
、delete
、in
、instanceof
。
语句
JavaScript中的语句是构成程序的基本单位,包括:
-
变量声明语句:
var
、let
、const
。 -
表达式语句:赋值、调用函数或执行算术运算。
-
条件语句:
if
、else
、switch
、case
、default
。 -
循环语句:
for
、while
、do...while
、for...in
、for...of
。 -
跳转语句:
break
、continue
、return
、throw
、try...catch
。 -
其他语句:
debugger
、with
(已弃用)、空语句、标签语句。
函数
函数是JavaScript中强大的编程工具,用于封装可重用的代码块。包括:
-
函数声明:使用
function
关键字。 -
函数表达式:将函数赋值给变量或常量。
-
箭头函数:使用
=>
语法。 -
函数参数:支持默认参数值、Rest参数和
arguments
对象。 -
函数返回值:使用
return
语句。 -
函数作用域和闭包:函数内的变量在函数外不可见,闭包可以访问其词法作用域中的变量。
-
高阶函数:接受一个或多个函数作为参数,或返回一个函数。
-
自调用函数(IIFE):定义后立即执行的函数。
-
函数递归:函数调用自身。
-
函数作为对象的方法:
this
关键字指向调用该方法的对象。 -
异步函数:回调函数、Promise和Async/Await。
关键字
关键字是JavaScript中具有预定义功能的词汇,用于执行特定操作或定义语言结构。包括:
-
控制结构关键字:
if
、else
、switch
、case
、default
。 -
循环关键字:
for
、while
、do
、break
、continue
。 -
函数关键字:
function
、return
。 -
变量声明关键字:
var
、let
、const
。 -
作用域和上下文关键字:
this
、new
、delete
、typeof
、instanceof
、in
。 -
异常处理关键字:
try
、catch
、finally
、throw
。 -
类与模块关键字:
class
、extends
、super
、import
、export
。 -
其他关键字:
void
、yield
、await
、async
。
保留字
保留字是被JavaScript语言保留,但当前未作为关键字使用的词汇。这些词汇在未来版本中可能会被用作关键字,因此不能用作标识符。包括:
-
未来保留字:
enum
、implements
、interface
、package
、private
、protected
、public
、static
。 -
其他保留字:
await
、yield
。 -
已弃用或仅在特定环境中保留:
abstract
、boolean
、byte
、char
、double
、final
、float
、goto
、int
、long
、native
、short
、synchronized
、transient
、volatile
。
通过对这些JavaScript核心概念的掌握,可以为日后的高级开发和框架学习打下坚实的基础。希望这篇文章能帮助大家更好地理解和应用JavaScript,愿大家年年高升,无寒冬!