值得收藏的 JavaScript 速查表
这是 JavaScript 的速查表。它包含解释、代码示例、基本和重要的运算符、函数、原理、方法等等。它提供了对该语言的良好概述。
JavaScript
JavaScript 是一种编程语言,它支持大多数网站的动态行为。它与 HTML 和 CSS 并列,是网络运行的核心技术。
console.log()
该console.log()
方法用于将消息记录或打印到控制台。它也可以用于打印对象和其他信息。
console.log("Hi there!");
// Prints: Hi there!
字符串
'
字符串是一种原始数据类型。它们是由单引号或双引号括起来的任意字符(字母、空格、数字或符号)的组合"
。
let single = 'Wheres my bandit hat?';
let double = "Wheres my bandit hat?";
数字
数字是一种原始数据类型。它包括所有整数和浮点数的集合。
let amount = 6;
let price = 4.99;
布尔值
布尔值是一种原始数据类型。它们可以是true
或false
。
let lateToWork = true;
let isHoliday = false;
无效的
Null 是一种原始数据类型。它表示故意缺失值。在代码中,它表示为null
。
let x = null;
算术运算符
JavaScript 支持以下算术运算符:
- - 添加
- - 减法
- - 乘法
- / 分配
- % 模数
// Addition
5 + 5;
// Subtraction
10 - 5;
// Multiplication
5 * 10;
// Division
10 / 5;
// Modulo
10 % 5;
字符串长度
字符串的属性.length
返回组成该字符串的字符数。
let message = "good nite";
console.log(message.length);
// Prints: 9
console.log("howdy".length);
// Prints: 5
方法
方法返回有关对象的信息,并通过在实例后附加句点.
、方法名称和括号来调用。
图书馆
库包含可以通过在库名称后附加句点.
、方法名称和一组括号来调用的方法。
Math.random()
该Math.random()
函数返回一个浮点随机数,范围从 0(含)到 1(不含)。
// Returns a number between 0 and 1
Math.random();
Math.floor()
该Math.floor()
函数返回小于或等于给定数字的最大整数。
console.log(Math.floor(5.95));
// Prints: 5
单行注释
在 JavaScript 中,单行注释由两个连续的正斜杠创建//
。
// This line will denote a comment
多行注释
在 JavaScript 中,多行注释是通过/*
在行首和*/
行尾分别使用 来创建的。注释有很多用途,例如解释代码块或提供一些提示等等。
/*
The below configuration must be
changed before deployment.
*/
let baseUrl = "https://google.com/";
变量
变量是存储在计算机内存中的数据的容器。它通过一个描述性名称引用,程序员可以调用它来分配特定的值并检索它。
// examples of variables
let name = "Tammy";
const found = false;
var age = 3;
console.log(name, found, age);
// Tammy, false, 3
const
关键词
常量变量可以使用关键字 声明const
。它必须被赋值。任何重新赋值的操作const
都会导致 JavaScript 运行时错误。
const numberOfColumns = 4;
numberOfColumns = 8;
// TypeError: Assignment to constant variable.
let
关键词
let
在 JavaScript 中创建一个局部变量,并且可以重新赋值。变量声明期间的初始化let
是可选的。let
如果没有赋值,变量将包含 undefined。
let count;
console.log(count); // Prints: undefined
count = 10;
console.log(count); // Prints: 10
不明确的
undefined
是一个原始的 JavaScript 值,表示缺少定义的值。已声明但未初始化为值的变量将具有值undefined
。
let a;
console.log(a);
// Prints: undefined
赋值运算符
赋值运算符根据右操作数的值给左操作数赋值。以下是其中一些:
- += 加法赋值
- -= 减法赋值
- *= 乘法赋值
- /= 除法赋值
let number = 100;
// Both statements will add 10
number = number + 10;
number += 10;
console.log(number);
// Prints: 120
字符串连接
在 JavaScript 中,可以使用运算符将多个字符串连接在一起+
。在示例中,多个字符串和包含字符串值的变量已被连接在一起。执行代码块后,displayText
变量将包含连接后的字符串。
let service = 'credit card';
let month = 'May 30th';
let displayText = 'Your ' + service + ' bill
is due on ' + month + '.';
console.log(displayText);
// Prints: Your credit card bill is due on May 30th.
字符串插值
字符串插值是评估包含一个或多个占位符(表达式、变量等)的字符串字面量的过程。它可以使用模板字面量来执行text ${expression} text
:
let age = 7;
// String concatenation
"Tommy is " + age + " years old.";
// String interpolation
`Tommy is ${age} years old.`;
模板字符串
模板字面量是允许嵌入表达式的字符串${expression}
。常规字符串使用单引号'
或双"
引号,而模板字面量则使用反引号。
let name = "Codecademy";
console.log(`Hello, ${name}`);
// Prints: Hello, Codecademy
console.log(`Billy is ${6 + 8} years old.`);
// Prints: Billy is 14 years old.
条件语句
控制流
控制流是指程序中语句的执行顺序。默认的控制流是按照程序文件中从左到右、从上到下的顺序读取和执行语句。
诸如条件语句(if 语句等)之类的控制结构会改变控制流,仅在满足特定条件时执行代码块。这些结构本质上允许程序在运行时决定执行哪些代码。
真值与假值
在 JavaScript 中,当值被评估为布尔值时,其结果为true
或。false
- 评估结果
true
为真值 false
计算结果为假的值
假值包括false
、0
、空字符串null
、undefined
、 和NaN
。所有其他值均为真值
比较运算符
比较运算符用于比较两个值并根据比较的有效性返回true
或:false
● === 严格等于
● !== 严格不等于
● == 宽松等于
● > 大于
● >= 大于或等于
● < 小于
● <= 小于或等于
1 > 3; // false
3 > 1; // true
250 >= 250; // true
1 === 1; // true
1 === 2; // false
1 === "1"; // false
1 == "1"; // true
if
陈述
语句if
接受带有一对括号的表达式:
- 如果表达式计算结果为真值,则执行其代码主体内的代码。
- 如果表达式计算结果为假值,则其代码主体将不会执行。
const isMailSent = true;
if (isMailSent) {
console.log("Mail sent to recipient");
}
if...else
陈述
可以将一个else
块添加到一个if
块或一系列if-else if
块中。else
只有当条件不满足时,才会执行该块if
。
const isTaskCompleted = false;
if (isTaskCompleted) {
console.log("Task completed");
} else {
console.log("Task incomplete");
}
else if
条款
在初始if
块之后,else if
每个块可以检查一个附加条件。else
可以在块之后添加一个可选块,else if
当所有条件均不成立时,该块默认运行。
const size = 10;
if (size > 100) {
console.log("Big");
} else if (size > 20) {
console.log("Medium");
} else if (size > 4) {
console.log("Small");
} else {
console.log("Tiny");
}
// Print: Small
逻辑非运算符
逻辑 NOT 运算符!
可用于执行以下操作之一:
- 反转布尔值。
- 反转非布尔值的真实性。
let lateToWork = true;
let oppositeValue = !lateToWork;
console.log(oppositeValue);
// Prints: false
逻辑与运算符
逻辑与运算符&&
检查两个值并返回布尔值。如果两个值都为真,则返回true
。如果其中一个或两个值都为假,则返回false
。
一个 | B | A && B |
---|---|---|
错误的 | 错误的 | 错误的 |
错误的 | 真的 | 错误的 |
真的 | 错误的 | 错误的 |
真的 | 真的 | 真的 |
true && true; // true
1 > 2 && 2 > 1; // false
true && false; // false
4 === 4 && 3 > 1; // true
逻辑或运算符
逻辑或运算符||
检查两个值并返回布尔值。如果其中一个或两个值都为真,则返回 true 。如果两个值都为假,则返回false
。
一个 | B | 全部 B |
---|---|---|
错误的 | 错误的 | 错误的 |
错误的 | 真的 | 真的 |
真的 | 错误的 | 真的 |
真的 | 真的 | 真的 |
true || false; // true
10 > 5 || 10 > 20; // true
false || false; // false
10 > 100 || 10 > 20; // false
switch
陈述
这些switch
语句提供了一种根据多个子句检查表达式的方法case
。如果某个案例匹配,则执行该子句内的代码。该case
子句应以关键字结尾break
。如果没有案例匹配但default
包含子句,default
则执行子句内的代码。
注意:如果在 case 块中省略了 break,则 switch 语句将继续检查 case 值,直到遇到 break 或流程被打破。
const food = "salad";
switch (food) {
case "oyster":
console.log("The taste of the sea 🦪");
break;
case "pizza":
console.log("A delicious pie 🍕");
break;
default:
console.log("Enjoy your meal");
}
// Prints: Enjoy your meal
三元运算符
三元运算符允许在二元(在两个选项之间进行选择)决策的情况下使用紧凑的语法。它接受一个条件,后跟一个?
运算符,然后是两个用 分隔的表达式:
。如果条件计算结果为真,则执行第一个表达式,否则执行第二个表达式。
let price = 10.5;
let day = "Monday";
day === "Monday" ? (price -= 1.5) : (price += 1.5);
// Price will be 9
功能
函数是 JavaScript 的基本构造块之一。函数是一组可重用的语句,用于执行任务或计算值。函数可以传递一个或多个值,并在执行结束时返回一个值。为了使用函数,你必须在希望调用它的作用域内定义它。
提供的示例代码包含一个函数,该函数接受 2 个值并返回它们的总和。
// Defining the function:
function sum(num1, num2) {
return num1 + num2;
}
// Calling the function:
sum(3, 6); // 9
调用函数
函数可以在代码的其他位置使用函数名后的括号来调用或执行。当函数被调用时,其函数体中的代码就会运行。参数是调用函数时传递给函数的值。
// Defining the function
function sum(num1, num2) {
return num1 + num2;
}
// Calling the function
sum(2, 4); // 6
函数参数
声明或定义函数时,函数的输入称为参数。参数在函数体内用作变量。调用函数时,这些参数的值将与传入的参数相同。也可以定义一个不带参数的函数。
// The parameter is name
function sayHello(name) {
return `Hello, ${name}!`;
}
// function without parameter
function sayHello() {
return `Hello, World!`;
}
return
关键词
函数使用关键字 来返回(传递)值return
。return
结束函数执行并将指定值返回到调用它的位置。一个常见的错误是忘记return
关键字,在这种情况下,函数将undefined
默认返回。
// With return
function sum(num1, num2) {
return num1 + num2;
}
// Without return, so the function doesn't output the sum
function sum(num1, num2) {
num1 + num2;
}
函数声明
函数声明用于创建命名函数。这些函数可以通过其声明的名称来调用。函数声明由以下部分构成:
- 关键字
function
。 - 函数名称。
- 可选的参数列表,以逗号分隔,并用一对括号括起来
()
。 - 函数体包含在一对花括号中
{}
function add(num1, num2) {
return num1 + num2;
}
匿名函数
JavaScript 中的匿名函数没有 name 属性。它们可以使用function
关键字或箭头函数来定义。请参阅代码示例,了解命名函数和匿名函数之间的区别。
// Named function
function rocketToMars() {
return "BOOM!";
}
// Anonymous function
const rocketToMars = function () {
return "BOOM!";
};
箭头函数
ES6 中引入了箭头函数表达式。这些表达式简洁明了。箭头函数表达式的语法不需要function
关键字,而是使用粗箭头=>
将参数与函数主体分隔开。箭头函数有几种变体:
-
具有单个参数的箭头函数不需要
()
围绕参数列表。 -
单个表达式的箭头函数可以使用简洁的函数体,返回不带关键字的表达式结果
return
。
// Arrow function with two arguments
const sum = (firstParam, secondParam) => {
return firstParam + secondParam;
};
console.log(sum(2, 5)); // Prints: 7
// Arrow function with no arguments
const printHello = () => {
console.log("hello");
};
printHello(); // Prints: hello
// Arrow functions with a single argument
const checkWeight = (weight) => {
console.log(`Baggage weight : ${weight} kilograms.`);
};
checkWeight(25); // Prints: Baggage weight : 25 kilograms.
// Concise arrow functions
const multiply = (a, b) => a * b;
console.log(multiply(2, 30)); // Prints: 60
范围
作用域是一个概念,指的是值和函数在何处可以被访问。各种作用域包括:
- 全局范围(全局范围内的值/函数可以在整个程序的任何地方使用)。
- 文件或模块范围(只能从文件内部访问值/函数)。
- 函数作用域(仅在函数内可见)。
- 代码块范围(仅在代码块内可见
{...}
)
function myFunction() {
var pizzaName = "Volvo";
// Code here can use pizzaName
}
// Code here can't use pizzaName
块范围变量
const
和let
是块级作用域变量,这意味着它们只能在其所在的块或嵌套块中访问。在给定的代码块中,尝试statusMessage
使用console.log()
方法打印 将导致ReferenceError
。它只能在该if
块内部访问。
const isLoggedIn = true;
if (isLoggedIn == true) {
const statusMessage = "User is logged in.";
}
console.log(statusMessage);
// Uncaught ReferenceError: statusMessage is not defined
全局变量
在代码块或函数之外声明的 JavaScript 变量可以存在于全局作用域中,这意味着它们在整个程序中都可以访问。在较小的代码块或函数作用域之外声明的变量可以在这些较小的作用域内访问。
注意:最佳做法是将全局变量保持在最低限度。
// Variable declared globally
const color = "blue";
function printColor() {
console.log(color);
}
printColor(); // Prints: blue
数组
数组是有序存储数据的列表。它们可以容纳任何数据类型的项目。数组使用方括号创建,各个元素之间用逗号分隔。
// An array containing numbers
const numberArray = [0, 1, 2, 3];
// An array containing different data types
const mixedArray = [1, "chicken", false];
指数
数组元素按索引值排列,从0
第一个元素索引开始。可以使用数组名称和方括号括起来的索引来访问元素[]
。
// Accessing an array element
const myArray = [100, 200, 300];
console.log(myArray[0]); // 100
console.log(myArray[1]); // 200
console.log(myArray[2]); // 300
财产.length
.length
JavaScript 数组的属性表示数组
包含的元素数量。
const numbers = [1, 2, 3, 4];
numbers.length; // 4
方法.push()
JavaScript 数组的方法.push()
可用于将一个或多个元素添加到数组的末尾。.push()
变异原始数组返回数组的新长度。
// Adding a single element:
const cart = ["apple", "orange"];
cart.push("pear");
// Adding multiple elements:
const numbers = [1, 2];
numbers.push(3, 4, 5);
方法.pop()
该.pop()
方法从数组中删除最后一个元素
并返回该元素。
const ingredients = ["eggs", "flour", "chocolate"];
const poppedIngredient = ingredients.pop(); // ("chocolate");
console.log(ingredients); // ['eggs', 'flour']
可变的
JavaScript 数组是可变的,这意味着它们包含的值可以改变。
即使使用 声明它们,也可以通过重新分配内部值或使用和const
等方法操纵内容。.push()
.pop()
const names = ["Alice", "Bob"];
names.push("Carl");
// ['Alice', 'Bob', 'Carl']
循环
循环是一种用于重复执行一组
指令的编程工具。“迭代”是一个通用术语,
在循环上下文中表示“重复”。循环将持续迭代,直到满足
指定的条件(通常称为停止条件) 。
for
环形
循环for
声明循环指令,其中三个重要信息用分号分隔;
- 初始化通过声明迭代器变量来定义循环的开始位置。
- 停止条件决定何时停止循环。
- 每次循环完成时,迭代语句都会更新迭代器。
for (let i = 0; i < 3; i += 1) {
console.log(i);
}
// Output: 0, 1, 2
反向循环
循环for
可以通过将循环变量初始化为起始值、测试变量何时达到结束值以及在每次迭代时减少(减去)循环变量来“反向”迭代。
const items = ["apricot", "banana", "cherry"];
for (let i = items.length - 1; i >= 0; i -= 1) {
console.log(`${i}. ${items[i]}`);
}
// Prints: 2. cherry
// Prints: 1. banana
// Prints: 0. apricot
循环遍历数组
可以使用 属性来计算数组的长度.length
。这对于循环遍历数组非常有用,因为.length
数组的长度可以用作循环的停止条件。
for (let i = 0; i < array.length; i++) {
console.log(array[i]);
}
// Output: Every item in the array
嵌套 For 循环
嵌套for
循环是指一个 for 循环在另一个for
循环内运行。外层循环每次迭代后,内层循环都会运行其所有迭代。
for (let outer = 0; outer < 2; outer += 1) {
for (let inner = 0; inner < 3; inner += 1) {
console.log(`${outer}-${inner}`);
}
}
/*
Output:
0-0
0-1
0-2
1-0
1-1
1-2
*/
While 循环
循环while
创建一个循环,只要指定的条件满足 ,循环就会执行true
。循环将持续运行,直到条件满足false
。条件在循环之前指定,通常会在while
循环体中增加或修改某个变量来确定循环何时停止。
语法:
while (condition) {
// code block to be executed
}
例子:
let i = 0;
while (i < 5) {
console.log(i);
i++;
}
Do…While 语句
语句do...while
创建一个循环,该循环执行一次代码块,检查条件是否为真,然后只要条件为真就重复循环。当你希望代码始终至少执行一次时,可以使用它们。当条件计算为假时,循环结束。
x = 0;
i = 0;
do {
x = x + i;
console.log(x);
i++;
} while (i < 5);
// Prints: 0 1 3 6 10
break
关键词
在循环中,可以使用break关键字立即退出循环,继续执行循环体之后的内容。
for (let i = 0; i < 99; i += 1) {
if (i > 5) {
break;
}
console.log(i);
}
// Output: 0 1 2 3 4 5
这里,break
关键字用于当i
大于5时退出循环。
迭代器
分配给变量的函数
在 JavaScript 中,函数是一种数据类型,就像字符串、数字和数组一样。因此,函数可以作为值赋给变量,但与所有其他数据类型不同,函数可以被调用。
let plusFive = (number) => {
return number + 5;
};
// f is assigned the value of plusFive
let f = plusFive;
plusFive(3); // 8
// Since f has a function value, it can be invoked.
f(9); // 14
高阶函数
在 JavaScript 中,函数可以像字符串或数组一样赋值给变量。它们可以作为参数传递给其他函数,也可以从其他函数返回。
“高阶函数”是接受函数作为参数和/或返回函数的函数。
回调函数
在 JavaScript 中,回调函数是作为参数传递给另一个函数的函数。该函数可以在高阶函数(作为其参数)执行期间被调用。
由于在 JavaScript 中函数是对象,因此函数可以作为参数传递。
const isEven = (n) => {
return n % 2 == 0;
};
let printMsg = (evenFunc, num) => {
const isNumEven = evenFunc(num);
console.log(`The number ${num} is an even
number: ${isNumEven}.`);
};
// Pass in isEven as the callback function
printMsg(isEven, 4);
// Prints: The number 4 is an even number: True.
数组方法.forEach()
该.forEach()
方法按顺序对数组中的每个元素执行回调函数。这里,包含console.log()
方法的回调函数将被执行5
一次,每个元素执行一次。
const numbers = [28, 77, 45, 99, 27];
numbers.forEach((number) => {
console.log(number);
});
数组方法.map()
该.map()
方法对数组中的每个元素执行回调函数。它返回一个由回调函数的返回值组成的新数组。
原始数组不会被改变,并且返回的数组可能包含与原始数组不同的元素。
const finalParticipants = ["Taylor", "Donald", "Don", "Natasha", "Bobby"];
const announcements = finalParticipants.map((member) => {
return member + " joined the contest.";
});
console.log(announcements);
数组方法.filter()
该.filter()
方法对数组中的每个元素执行回调函数。每个元素的回调函数必须返回true
或false
。返回的数组是一个新数组,其中包含回调函数返回 的所有元素true
。此处,数组将包含除 之外filteredArray
的所有元素。randomNumbers
4
const randomNumbers = [4, 11, 42, 14, 39];
const filteredArray = randomNumbers.filter((n) => {
return n > 5;
});
数组方法.reduce()
该.reduce()
方法遍历一个数组并返回一个值。它接受一个回调函数,该函数包含两个参数(accumulator 和 currentValue)。每次迭代时,accumulator
accumulator 是上次迭代的返回值,currentValue 是当前元素。(可选)可以传递第二个参数作为累加器的初始值。此处,该.reduce()
方法将对数组的所有元素求和。
const arrayOfNumbers = [1, 2, 3, 4];
const sum = arrayOfNumbers.reduce((accumulator, currentValue) => {
return accumulator + currentValue;
});
console.log(sum); // 10
对象
对象是一种用于存储键值对的内置数据类型。对象内部的数据是无序的,值可以是任何类型。
JavaScript 对象的属性和值
JavaScript 对象字面量用花括号括起来{}
。值通过冒号 ( :
) 映射到对象中的键,键值对之间用逗号分隔。所有键都是唯一的,但值不是唯一的。对象的键值对也称为属性。
const classOf2018 = {
students: 38,
year: 2018,
};
属性命名的限制
JavaScript 对象的键名必须遵循一些限制才能有效。键名必须是字符串、有效的标识符或变量名(例如,-
非字符串的键名中不允许使用 等特殊字符)。
// Example of invalid key names
const trainSchedule = {
platform num: 10, // Invalid because of the space between words.
40 - 10 + 2: 30, // Expressions cannot be keys.
+compartment: 'C' // The use of a + sign is invalid unless it is enclosed in quotations.
}
用于访问对象属性的点符号
可以使用点符号按以下方式访问 JavaScript 对象的属性:
object.propertyName
可以通过按正确的顺序链接键名来访问对象的嵌套属性。
const apple = {
color: "Green",
price: {
bulk: "$3/kg",
smallQty: "$4/kg",
},
};
console.log(apple.color); // 'Green'
console.log(apple.price.bulk); // '$3/kg'
删除运算符
在 JavaScript 中创建对象后,可以使用 delete 运算符从对象中删除属性。该delete
关键字会同时删除对象中的属性值和属性本身。该delete
运算符仅适用于属性,不适用于变量或函数。
const person = {
firstName: "Matilda",
age: 27,
hobby: "knitting",
goal: "learning JavaScript",
};
delete person.hobby; // or delete person[hobby];
console.log(person);
/*
{
firstName: "Matilda"
age: 27
goal: "learning JavaScript"
}
*/
访问不存在的 JavaScript 属性
当尝试访问
尚未定义的 JavaScript 对象属性时,undefined
将默认返回的值。
const classElection = {
date: "January 12",
};
console.log(classElection.place); // undefined
JavaScript 对象是可变的
JavaScript 对象是可变的,这意味着即使它们被声明为 ,其内容也可以更改const
。可以添加新属性,也可以更改或删除现有属性值。绑定到变量的对象的引用是无法更改的。
const student = {
name: "Sheldon",
score: 100,
grade: "A",
};
console.log(student);
// { name: 'Sheldon', score: 100, grade: 'A' }
delete student.score;
student.grade = "F";
console.log(student);
// { name: 'Sheldon', grade: 'F' }
student = {};
// TypeError: Assignment to constant variable
JavaScript 对象方法
JavaScript 对象可以具有函数形式的属性值。这些被称为对象方法。方法可以使用匿名函数、箭头函数表达式或简写方法语法来定义。对象方法的调用语法如下:objectName.methodName(arguments)
const engine = {
// method shorthand, with one argument
start(adverb) {
console.log(`The engine starts up ${adverb}...`);
},
// anonymous arrow function expression with no arguments
sputter: () => {
console.log("The engine sputters...");
},
};
engine.start("noisily");
engine.sputter();
/* Console output:
The engine starts up noisily...
The engine sputters...
*/
JavaScript 将对象作为参数传递
当 JavaScript 对象作为参数传递给函数或方法时,它们是通过引用传递的,而不是通过值传递的。这意味着对象本身(而不是副本)在该函数内部是可访问且可变的(可以更改)。
const origNum = 8;
const origObj = { color: "blue" };
const changeItUp = (num, obj) => {
num = 7;
obj.color = "red";
};
changeItUp(origNum, origObj);
// Will output 8 since integers are passed by value.
console.log(origNum);
// Will output 'red' since objects are passed
// by reference and are therefore mutable.
console.log(origObj.color);
JavaScript for...in 循环
JavaScriptfor...in
循环可用于迭代对象的键。在每次迭代中,对象的一个属性会被赋值给该循环的变量。
let mobile = {
brand: "Samsung",
model: "Galaxy Note 9",
};
for (let key in mobile) {
console.log(`${key}: ${mobile[key]}`);
}
this 关键字
保留关键字 this 指的是方法的调用对象,它可用于访问属于该对象的属性。
这里,使用this
对象函数内的关键字来引用cat
对象并访问其name
属性。
const cat = {
name: "Goose",
age: 8,
whatName() {
return this.name;
},
};
console.log(cat.whatName());
// Output: Goose
Javascript 函数this
每个 JavaScript 函数或方法都有一个 this 上下文。对于定义在对象内部的函数,this
它将引用该对象本身。对于定义在对象外部的函数,this
它将引用全局对象(window
在浏览器中,global
在 Node.js 中)。
const restaurant = {
numCustomers: 45,
seatCapacity: 100,
availableSeats() {
// this refers to the restaurant object
// and it's used to access its properties
return this.seatCapacity - this.numCustomers;
},
};
JavaScript 箭头函数this
作用域
JavaScript 箭头函数没有自己的this
上下文,而是使用this
周围的词法上下文。因此,它们通常不适合用来编写对象方法。
考虑示例代码:
-
loggerA
是一个使用箭头符号定义函数的属性。由于data
不存在于全局上下文中,因此访问 会this.data
返回undefined
。 -
loggerB
使用方法语法,由于指的是封闭对象,因此可以按预期访问属性this
的值,返回。data
"abc"
const myObj = {
data: "abc",
loggerA: () => {
console.log(this.data);
},
loggerB() {
console.log(this.data);
},
};
myObj.loggerA(); // undefined
myObj.loggerB(); // 'abc'
JavaScript getter 和 setter 受到限制
JavaScript 对象属性既不是私有的也不是受保护的。由于 JavaScript 对象是通过引用传递的,因此无法完全阻止与对象属性的错误交互。
实现与对象属性更严格的交互的一种方法是使用 getter 和 setter 方法。通常,内部值存储为一个属性,其标识符与getter和setter方法名称匹配,但以下划线 ( _
)开头。
const myCat = {
_name: "Dottie",
get name() {
return this._name;
},
set name(newName) {
this._name = newName;
},
};
// Reference invokes the getter
console.log(myCat.name);
// Assignment invokes the setter
myCat.name = "Yankee";
getter 和 setter 拦截属性访问
JavaScript getter 和 setter 方法很有用,因为它们提供了一种拦截属性访问和分配的方法,并允许在这些更改生效之前执行其他操作。
const myCat = {
_name: 'Snickers',
get name(){
return this._name
},
set name(newName){
//Verify that newName is a non-empty
string before setting as name property
if (typeof newName === 'string' && newName.length > 0){
this._name = newName;
} else {
console.log("ERROR: name must be a nonempty string");
}
}
}
Javascript 工厂函数
返回对象的 JavaScript 函数称为工厂函数。工厂函数通常接受参数以自定义返回的对象。
// A factory function that accepts 'name',
// 'age', and 'breed' parameters to return
// a customized dog object.
const dogFactory = (name, age, breed) => {
return {
name: name,
age: age,
breed: breed,
bark() {
console.log("Woof!");
},
};
};
JavaScript 解构赋值简写语法
JavaScript解构赋值是一种简写语法,允许将对象属性提取到特定的变量值中。
它使用一对{}
带有属性名的花括号在赋值语句的左侧,从对象中提取值。变量的数量可以少于对象的属性总数。
const rubiksCubeFacts = {
possiblePermutations: "43,252,003,274,489,856,000",
invented: "1974",
largestCube: "17x17x17",
};
const { possiblePermutations, invented, largestCube } = rubiksCubeFacts;
console.log(possiblePermutations); //
("43,252,003,274,489,856,000");
console.log(invented); // '1974'
console.log(largestCube); // '17x17x17'
对象创建的简写属性名称语法
JavaScript 中的简写属性名语法允许创建对象而无需显式指定属性名(即在键后显式声明值)。在此过程中,会创建一个对象,该对象的属性名与该上下文中已存在的变量匹配。简写属性名会使用与标识符匹配的键和与标识符值匹配的值来填充对象。
const activity = "Surfing";
const beach = { activity };
console.log(beach); // { activity: 'Surfing' }
课程
JavaScript 支持使用类的概念作为创建对象的语法。类指定了由该类生成的对象所具有的共享属性和方法。
当基于类创建一个对象时,该新对象被称为该类的一个实例。使用new
关键字创建新的实例。
代码示例展示了一个表示 的类。在类下创建了Song
一个名为 的新对象,并调用了该类上的方法。结果将是控制台中打印的文本“Song”。mySong
.play()
playing!
class Song {
constructor() {
this.title;
this.author;
}
play() {
console.log("Song playing!");
}
}
const mySong = new Song();
mySong.play();
类构造函数
类可以拥有constructor
方法。这是一种特殊的方法,在对象创建(实例化)时调用。构造函数通常用于设置对象的初始值。
class Song {
play() {
console.log("Playing!");
}
stop() {
console.log("Stopping!");
}
}
extends
JavaScript 类支持继承的概念——子类可以扩展父类。这是通过在类定义中使用 extends 关键字来实现的。
子类可以访问父类的所有实例属性和方法。此外,它们还可以添加自己的属性和方法。子类构造函数使用该super()
方法调用父类构造函数。
// Parent class
class Media {
constructor(info) {
this.publishDate = info.publishDate;
this.name = info.name;
}
}
// Child class
class Song extends Media {
constructor(songData) {
super(songData);
this.artist = songData.artist;
}
}
const mySong = new Song({
artist: "Queen",
name: "Bohemian Rhapsody",
publishDate: 1975,
});
静态方法
在 JavaScript 类中,static
关键字 为类定义了一个静态方法。静态方法不会在类的单个实例上调用,而是在类本身上调用。因此,它们往往是通用(实用)方法。
class Dog {
constructor(name) {
this._name = name;
}
introduce() {
console.log("This is " + this._name + "!");
}
// A static method
static bark() {
console.log("Woof!");
}
}
const myDog = new Dog("Buster");
myDog.introduce();
// Calling the static method
Dog.bark();
模块
使用 require 函数导入 Javascript 模块
在 Node.js 中,该require
函数可用于将代码从另一个文件导入到当前脚本中。
var moduleA = require("./module-a.js");
// The .js extension is optional
var moduleA = require("./module-a");
// Both ways will produce the same result.
// Now the functionality of moduleA can be used
console.log(moduleA.someFunctionality);
中级 Javascript:导出模块
为了使我们的 Javascript 文件中的对象可以作为 Node.js 中的模块导出,我们将该对象分配给exports
的属性module
。
let Course = {};
Course.name = "Javascript Node.js";
module.exports = Course;
Javascript 导出默认
从 ES6 开始,export default 关键字允许导出单个变量或函数,然后,在另一个脚本中,可以直接导入默认导出。
使用导出默认值后,可以导入变量或函数而不使用该require()
函数。
// module "moduleA.js"
export default function cube(x) {
return x * x * x;
}
// In main.js
import cube from "./moduleA.js";
// Now the `cube` function can be used
straightforwardly.console.log(cube(3)); // 27
import
在 Javascript 中使用关键字
从 ES6 开始,import
关键字可用于导入先前导出到 当前脚本的
函数、对象或原语。
有很多种使用import
关键字的方法,例如,您可以 使用选择器
从脚本导入所有导出,如下所示:*
import * from 'module_name';
可以使用花括号导入单个函数,如下
所示:
import {funcA} as name from 'module_name';
或者按名称排列多个函数:
import {funcA, funcB} as name from 'module_name';
承诺
JavaScript Promise 对象
JavaScript是一个对象, 当异步操作的结果 不能立即获得时Promise
,可以使用它来获取该结果。
由于 JavaScript 代码以非阻塞方式运行,因此
当我们必须等待
某些异步操作而不阻止
其余代码的执行时,承诺就变得至关重要。
JavaScript Promise 的状态
JavaScript Promise 对象可以处于以下三种状态之一:pending、solved或rejected。当值尚未可用时,Promise会保持此pending
状态。之后,它会转换为以下两种状态之一:resolved
或rejected
。 已解决的 Promise 代表成功完成。由于出现错误,Promise 可能会进入此rejected
状态。
在给定的代码块中,如果Promise处于开启resolved
状态,则该方法的第一个参数(包含回调函数)then()
将打印解析后的值。否则,将显示一个警报。
const promise = new Promise((resolve, reject) => {
const res = true;
// An asynchronous operation.
if (res) {
resolve("Resolved!");
} else {
reject(Error("Error"));
}
});
promise.then(
(res) => console.log(res),
(err) => alert(err)
);
创建 Javascript Promise 对象
使用关键字创建JavaScript Promise对象的实例new
。
Promise对象的构造函数接受一个称为执行函数的函数作为参数。该函数负责解决或拒绝该 Promise。
const executorFn = (resolve, reject) => {
console.log("The executor function of the promise!");
};
const promise = new Promise(executorFn);
JavaScript Promise 对象的执行函数
JavaScript Promise 的执行函数接受两个函数作为参数。第一个参数表示应调用以解析 Promise 的函数,另一个参数表示应拒绝 Promise 时使用的函数。Promise
对象可以在其执行函数中使用其中任何一个,或者同时使用这两个函数。
在给定的示例中,该resolve
函数始终无条件地解决 Promise。该rejected
函数可以用于拒绝。
const executorFn = (resolve, reject) => {
resolve("Resolved!");
};
const promise = new Promise(executorFn);
设置超时()
setTimeout()
是一个异步 JavaScript 函数,它在设置的毫秒延迟后通过回调函数执行代码块或评估表达式。
const loginAlert = () => {
alert("Login");
};
setTimeout(loginAlert, 6000);
.then()
JavaScript Promise 对象的方法
JavaScript Promise 对象的方法.then()
可用于获取异步操作的最终结果(或错误)。
.then()
接受两个函数参数。如果 Promise 已解决,则将调用提供给它的第一个处理程序。如果 Promise 被拒绝,则将调用第二个处理程序。
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Result");
}, 200);
});
promise.then(
(res) => {
console.log(res);
},
(err) => {
alert(err);
}
);
链接多个.then()
方法
即使其中一个或两个处理函数都不存在,该.then()
方法也会返回一个 Promise。因此,多个.then()
方法可以链接在一起。这称为组合。
在代码块中,几个.then()
方法被链接在一起。每个方法处理各自 Promise 的解析值。
const promise = new Promise((resolve) =>
setTimeout(() => resolve("dAlan"), 100)
);
promise
.then((res) => {
return res === "Alan"
? Promise.resolve("Hey Alan!")
: Promise.reject("Who are you?");
})
.then(
(res) => {
console.log(res);
},
(err) => {
alert(err);
}
);
.catch()
处理拒绝的方法
.then()
当 Promise 被拒绝时,将使用作为第二个参数传递给 Promise 对象方法的函数。此方法的另一种方法是使用.catch()
Promise 对象的 JavaScript 方法。方法中提供的处理程序可以获取拒绝信息.catch()
。
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
reject(Error("Promise Rejected Unconditionally."));
}, 1000);
});
promise.then((res) => {
console.log(value);
});
promise.catch((err) => {
alert(err);
});
避免嵌套 Promise 和.then()
在 JavaScript 中,当按顺序执行多个异步操作时,Promise 应该通过链接多个.then()
方法来组合。这比嵌套更好。
链接有助于简化开发过程,因为它使代码更具可读性且更易于调试。
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("*");
}, 1000);
});
const twoStars = (star) => {
return star + star;
};
const oneDot = (star) => {
return star + ".";
};
const print = (val) => {
console.log(val);
};
// Chaining them all together
promise.then(twoStars).then(oneDot).then(print);
JavaScriptPromise.all()
JavaScriptPromise.all()
方法可用于并行执行多个 Promise。该函数接受一个 Promise 数组作为参数。如果参数中的所有 Promise 都已解析,则返回的 PromisePromise.all()
将解析为一个数组,其中包含所有 Promise 的解析值,解析顺序与初始数组的顺序一致。Promise 列表中的任何拒绝都会导致较大的 Promise 被拒绝。在代码块中,即使会在 之后解析,3
和也会分别打印出来。2
promise1
promise2
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(3);
}, 300);
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(2);
}, 200);
});
Promise.all([promise1, promise2]).then((res) => {
console.log(res[0]);
console.log(res[1]);
});
异步等待
ES6 中的 async...await 语法提供了一种编写更具可读性和可扩展性的代码来处理 Promise 的新方法。它使用了 JavaScript 中现有的所有功能。
function helloWorld() {
return new Promise((resolve) => {
setTimeout(() => {
resolve("Hello World!");
}, 2000);
});
}
async function msg() {
const msg = await helloWorld();
console.log("Message:", msg);
}
msg(); // Message: Hello World! <-- after 2 seconds
异步 JavaScript 函数
异步 JavaScript 函数可以async
在函数名称前使用 关键字创建function
,或者()
在使用 async 箭头函数时,也可以在函数名称前使用 关键字创建。async
函数始终返回一个 Promise。
function helloWorld() {
return new Promise((resolve) => {
setTimeout(() => {
resolve("Hello World!");
}, 2000);
});
}
const msg = async function () {
//Async Function Expression
const msg = await helloWorld();
console.log("Message:", msg);
};
const msg1 = async () => {
//Async Arrow Function
const msg = await helloWorld();
console.log("Message:", msg);
};
msg(); // Message: Hello World! <-- after 2 seconds
msg1(); // Message: Hello World! <-- after 2 seconds
JavaScriptasync...await
运算符
ES6 中的JavaScriptasync...await
语法提供了一种新的方式来编写更具可读性和可扩展性的代码来处理 Promise。JavaScriptasync
函数可以包含以await
运算符开头的语句。运算符的操作数await
是一个 Promise。在await
表达式处,函数的执行async
暂停,并等待操作数 Promise 解析。await
运算符返回 Promise 的解析值。await
操作数只能在async
函数内部使用。
function helloWorld() {
return new Promise((resolve) => {
setTimeout(() => {
resolve("Hello World!");
}, 2000);
});
}
async function msg() {
const msg = await helloWorld();
console.log("Message:", msg);
}
msg(); // Message: Hello World! <-- after 2 seconds;
JavaScript async…await 的优势
JavaScriptasync...await
语法允许在程序执行过程中根据需要发起多个 Promise,并解析这些 Promise 的值。作为链式.then()
函数的替代方案,它提供了更好的代码可维护性,并且与同步代码非常相似。
异步函数错误处理
JavaScriptasync
函数使用try...catch
语句进行错误处理。此方法允许同步和异步代码共享错误处理。
let json = '{ "age": 30 }'; // incomplete data
try {
let user = JSON.parse(json); // <-- no
errors;
alert(user.name); // no name!
} catch (e) {
alert("Invalid JSON data!");
}
使用 async await 语法
构造一个或多个不带关键字的 Promise 或调用await
可以允许多个async
函数同时执行。通过这种方式,程序可以利用并发性,并且可以在async
函数内发起异步操作。由于使用await
关键字会暂停函数的执行async
,因此一旦程序逻辑需要每个异步函数的值,就可以等待该函数。
解析 JavaScript Promise
使用 JavaScript 时async...await
,多个异步操作可以并发运行。如果每个发起的 Promise 都需要解析值,Promise.all()
则可以使用它来检索解析值,从而避免不必要的阻塞。
let promise1 = Promise.resolve(5);
let promise2 = 44;
let promise3 = new Promise(function (resolve, reject) {
setTimeout(resolve, 100, "foo");
});
Promise.all([promise1, promise2, promise3]).then(function (values) {
console.log(values);
});
// expected output: Array [5, 44, "foo"]
请求
使用 XMLHttpRequest 进行异步调用
AJAX 不仅允许在网页加载期间发出 HTTP 请求,还可以在页面初始加载后的任何时间发出。这允许向网页添加动态行为。这对于提供良好的用户体验至关重要,无需重新加载网页即可与 Web 服务器之间传输数据。
XMLHttpRequest (XHR) Web API 提供了发出实际异步请求的能力,并使用 AJAX 处理来自请求的数据。
给定的代码块是如何向指定 URL 发出 HTTP GET 请求的基本示例。
const xhr = new XMLHttpRequest();
xhr.open("GET", "mysite.com/api/getjson");
HTTP POST 请求
HTTP
POST
发出请求的目的是将新信息发送到接收它的源(服务器)。
对于POST
请求,新信息存储在请求正文中。
HTTP GET 请求
HTTP
GET
发出请求的目的是从网络上的某个源(服务器)检索信息或数据。
GET
请求没有主体,因此为了返回正确的响应,源所需的信息必须包含在请求 URL 路径或查询字符串中。
URL 中的查询字符串
查询字符串用于在 HTTP GET 请求期间向服务器发送附加信息。
查询字符串与原始 URL 使用问号 分隔?
。在查询字符串中,可以有一个或多个由等号 连接的键值对=
。为了分隔多个键值对,&
使用与号。
如果存在 URL 不安全字符,则查询字符串应该进行 URL 编码。
const requestUrl = "http://mysite.com/api/vendor?name=kavin&id=35412";
JSON:JavaScript 对象表示法
JSON,即JavaScript 对象表示法,是一种适用于与服务器之间传输数据的数据格式。它本质上是 JavaScript 对象的一个稍微严格一些的版本。JSON 对象应该用花括号括起来,并且可以包含一个或多个属性值对。JSON 对象的名称需要使用双引号,而标准 JavaScript 对象则不需要。
const jsonObj = {
name: "Rick",
id: "11A",
level: 4,
};
XMLHttpRequest GET 请求要求
必须提供请求类型、响应类型、请求 URL 和响应数据的处理程序才能使用 JavaScript 发出 HTTP GET 请求XMLHttpRequest API
。
URL 可以在查询字符串中包含其他数据。对于 HTTPGET
请求,请求类型必须为GET
。
const req = new XMLHttpRequest();
req.responseType = "json";
req.open("GET", "/myendpoint/getdata?id=65");
req.onload = () => {
console.log(xhr.response);
};
req.send();
使用 XMLHttpRequest API 的 HTTP POST 请求
POST
要使用 JavaScript API发出 HTTP请求XMLHttpRequest
,必须提供请求类型、响应类型、请求 URL、请求正文以及响应数据的处理程序。请求正文至关重要,因为通过该POST
方法发送的信息在 URL 中不可见。请求类型必须适用POST
于这种情况。响应类型可以是多种类型,包括数组缓冲区、JSON 等。
const data = {
fish: "Salmon",
weight: "1.5 KG",
units: 5,
};
const xhr = new XMLHttpRequest();
xhr.open("POST", "/inventory/add");
xhr.responseType = "json";
xhr.send(JSON.stringify(data));
xhr.onload = () => {
console.log(xhr.response);
};
fetch()
方法
JavaScript Fetch API 用于访问和操作 HTTP 管道中的请求和响应,并通过网络异步获取资源。一个基本的fetch((
请求将接受一个 URL 参数,发送一个请求,并包含一个成功和失败的 Promise 处理函数。
在示例中,代码块首先调用fetch()
函数。然后,一个then()
方法被链接到函数的末尾fetch()
。最后,它以响应回调(用于处理成功)和拒绝回调(用于处理失败)结束。
fetch("url").then(
(response) => {
console.log(response);
},
(rejection) => {
console.error(rejection.message);
}
);
Response.ok
属性获取 API
在 Fetch API 函数中,响应的fetch()
属性ok
会检查其结果是否为true
或false
。在代码示例中,true
当 HTTP 请求成功时, .ok 属性将变为 。当 HTTP 请求失败时,.ok
属性将变为。false
fetch(url, {
method: "POST",
headers: {
"Content-type": "application/json",
"api-key": apiKey,
},
body: data,
}).then(
(response) => {
if (response.ok) {
return response.json();
}
throw new Error("Request failed!");
},
(networkError) => {
console.log(networkError.message);
}
);
获取 API 函数
Fetch API 函数fetch()
可用于创建请求。虽然接受其他参数,但请求可以自定义。这可用于更改请求类型、标头、指定请求正文等等,如示例代码块所示。
fetch("https://api-to-call.com/endpoint", {
method: "POST",
body: JSON.stringify({ id: "200" }),
})
.then(
(response) => {
if (response.ok) {
return response.json();
}
throw new Error("Request failed!");
},
(networkError) => {
console.log(networkError.message);
}
)
.then((jsonResponse) => {
console.log(jsonResponse);
});
[了解有关 fetch() 的更多信息]
JSON 格式的响应主体
该.json()
方法会将返回的 Promise 解析为 JSON 对象,并将响应体文本解析为 JSON。示例代码块展示了.json()
该方法如何返回一个 Promise,该 Promise 解析为 JSON 格式的响应体,并生成 JavaScript 对象。
fetch("url-that-returns-JSON")
.then((response) => response.json())
.then((jsonResponse) => {
console.log(jsonResponse);
});
使用Async...Await
该async…await
语法与 JS Fetch API 一起使用fetch()
,用于处理 Promise。在代码块示例中,我们看到关键字async
放置在函数中。这意味着该函数将返回一个 Promise。该关键字await
使 JavaScript 等待,直到问题得到解决。
const getSuggestions = async () => {
const wordQuery = inputField.value;
const endpoint = `${url}${queryParams}${wordQuery}`;
try {
const response = await fetch(endpoint, { cache: "no-cache" });
if (response.ok) {
const jsonResponse = await response.json();
}
} catch (error) {
console.log(error);
}
};
结论
如果你喜欢这篇文章,别忘了点赞❤️。如果你有任何疑问或建议,请随时提出。这篇文章很长,我知道我并没有涵盖所有内容,比如DOM操作,这些可以在另一篇文章中解释。保存以备后用⌛再见。