JavaScript 学习总结
JavaScript 是一种广泛用于前端开发的脚本语言,它为网页添加了动态交互和丰富的功能。
基础知识
- 理解 JavaScript 的基本语法、数据类型和变量声明。、
// 语法
console.log("Hello, world!");
// 数据类型和变量声明
let name = "coco";
const age = 28;
- 学习控制流程(条件语句和循环)以及函数的定义和调用。
控制流程涉及条件语句和循环:
// 条件语句
if (age >= 18) {
console.log("You are an adult.");
} else {
console.log("You are a minor.");
}
// 循环
for (let i = 0; i < 5; i++) {
console.log(i);
}
函数的定义和调用:
// 函数定义和调用
function greet(name) {
console.log("Hello, " + name + "!");
}
greet("coco");
- 知道如何处理数组和对象,并熟悉常用的数组和对象方法。
// 数组方法
const numbers = [1, 2, 3, 4, 5];
console.log(numbers.length); // 输出:5
numbers.push(6); // 添加元素到数组末尾
console.log(numbers); // 输出:[1, 2, 3, 4, 5, 6]
// 对象方法
const person = {
name: "coco",
age: 28,
};
console.log(person.name); // 输出:coco
person.age = 30; // 修改对象属性值
console.log(person); // 输出:{ name: 'coco', age: 28 }
- 掌握面向对象编程的概念和技巧。
// 创建类和实例化对象
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayHello() {
console.log("Hello, my name is " + this.name);
}
}
const coco = new Person("coco", 28);
coco.sayHello(); // 输出:Hello, my name is coco
DOM 操作
- 了解 Document Object Model(文档对象模型)的基本概念。
文档对象模型(Document Object Model,简称DOM)是一种用于表示和操作HTML、XML和SVG等文档的API。DOM提供了一组接口和方法,允许开发者通过JavaScript来访问和操控文档的结构、内容和样式。其中包含节点,元素,属性,文本,父子关系。通过使用DOM,可以通过JavaScript来选择和操作文档中的特定元素、修改元素的内容、样式和属性,以及动态地创建、移除和替换元素等。
- DOM是文档对象模型,可以使用 JavaScript 操纵 HTML 元素和样式。
// 获取元素并修改内容
const heading = document.getElementById("heading");
heading.innerHTML = "New Heading";
// 修改样式
const button = document.querySelector(".button");
button.style.backgroundColor = "red";
// 绑定事件处理器
button.addEventListener("click", function () {
console.log("Button clicked!");
});
- 熟悉事件处理器,能够通过 JavaScript 给元素绑定事件,如点击、鼠标移入/移出、键盘输入等,并在事件处理程序中编写相应的代码来响应用户的操作。
- 使用
addEventListener()
方法:将为具有id为myElement
的元素添加一个点击事件监听器。当该元素被点击时,事件处理程序中的代码将被执行。(addEventListener()
方法,可以将HTML和JavaScript代码分离,提高可维护性和可读性。)
const element = document.getElementById('myElement');
element.addEventListener('click', function() {
// 在此处编写事件处理程序
});
2.直接在HTML属性中添加事件处理函数:使用onclick
属性直接将事件处理函数myFunction()
与按钮元素进行绑定。当按钮被点击时,相应的函数将会被调用。
<button onclick="myFunction()">点击我</button>
<script>
function myFunction() {
// 在此处编写事件处理程序
}
</script>
3.使用匿名函数作为事件处理程序:querySelector()
方法选择具有.myClass
类的元素,并在鼠标悬停在该元素上时触发匿名函数作为事件处理程序。
const element = document.querySelector('.myClass');
element.addEventListener('mouseover', function() {
// 在此处编写事件处理程序
});
异步编程
- 理解 JavaScript 异步编程的原理和机制。JavaScript异步编程是为了处理耗时的操作或需要等待的事件,以提高程序的性能和用户体验。
首先进行初步学习我们可以了解到,JavaScript的异步编程机制的目的是在某些操作完成后才执行相应的代码,能够使程序继续运行而不会被阻塞。这样可以提高应用程序的性能、用户体验,并允许处理复杂的并发操作。
其中包含四个部分,第一个是回调函数-Callback,它允许指定一个函数作为参数,并在异步操作完成后调用该函数,例如,在AJAX请求完成后,可以通过回调函数来处理返回的数据。
第二个是Promise,它代表了一个异步操作的最终结果,可以使程序拥有更好的可读性和错误处理。它可以处于三个状态之一:pending(进行中)、fulfilled(已成功)或rejected(已失败)。当异步操作完成时,Promise会根据结果状态选择相应的回调函数执行。
第三个是异步函数(Async/Await,它简化了Promise的使用。在函数前面添加async
关键字,就可以使其成为一个异步函数。在异步函数内部,await
关键字可以暂停函数的执行,等待Promise解决或拒绝,最后在解决后返回结果。
第四个是事件驱动(Event-driven):当某个事件发生时,会触发相应的事件处理程序,并执行特定的操作。例如,鼠标点击、键盘输入和定时器等事件,都可以通过添加事件监听器来处理。
- 学会使用回调函数、Promise 和 async/await 处理异步操作。
使用回调函数:
function fetchData(callback) {
setTimeout(function () {
const data = "Data fetched!";
callback(data);
}, 2000);
}
fetchData(function (data) {
console.log(data); // 输出:Data fetched!
});
使用 Promise:
function fetchData() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
const data = "Data fetched!";
resolve(data);
}, 2000);
});
}
fetchData().then(function (data) {
console.log(data); // 输出:Data fetched!
});
使用 async/await:
function fetchData() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
const data = "Data fetched!";
resolve(data);
}, 2000);
});
}
async function fetchAndPrintData() {
const data = await fetchData();
console.log(data); // 输出:Data fetched!
}
fetchAndPrintData();
- 掌握如何发送 AJAX 请求并处理响应。
使用Promise和fetch API来发送AJAX请求
// 发送AJAX请求并返回Promise对象
function sendAjaxRequest(url) {//该函数的参数是url
return fetch(url)//发送GET请求
.then(response => {
if (!response.ok) {
throw new Error('请求失败');//如果相应的状态码不为200,就会错误
}
return response.json();//否则就会将相应的JSON数据解析后返回给后续的.then回调函数
});
}
// 使用sendAjaxRequest函数发送AJAX请求并处理响应
sendAjaxRequest('https://api.example.com/data')
.then(data => {
// 处理响应数据
console.log(data);
})
.catch(error => {
// 处理错误情况
console.error(error);
});
常见库和框架
- 了解常用的 JavaScript 库和框架,如 jQuery、React 和 Vue.js。
- 学习如何使用这些库和框架来简化开发过程和提高效率。
使用 jQuery 操纵 DOM:
$(document).ready(function () {
$("#heading").text("New Heading");
$(".button").css("background-color", "red");
$(".button").click(function () {
console.log("Button clicked!");
});
});
使用 React 创建组件:
import React from "react";
class Greeting extends React.Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}
export default Greeting;
使用Vue.js绑定数据,修改数据:
<!DOCTYPE html>
<html>
<head>
<title>Vue.js Example</title>//引入Vue.js库
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h1>{{ message }}</h1>
<button @click="changeMessage">Change Message</button>//将按钮的点击事件与Vue示例中的changeMessage相关联,当点击按钮时,就会触发changeMessage,更新message的值。
</div>
<script>
// 在JavaScript中创建Vue实例
var app = new Vue({
el: '#app',//指定el为#app
data: {
message: 'Hello Vue!'//用于在模板中显示信息
},
methods: {
changeMessage() {
this.message = 'New Message!';
}
}
});
</script>
</body>
</html>
TypeScript学习总结
TypeScript 是 JavaScript 的超集,它在JavaScript的基础上添加了类型系统。通过类型系统,TypeScript可以在编译阶段发现和预防许多常见的错误,并拥有了更好的代码提示和自动补全功能。
静态类型检查
- 了解 TypeScript 的类型系统和如何声明变量、函数和对象的类型。
基本类型声明变量:
number
:表示数字类型,例如:let age: number = 25;
string
:表示字符串类型,例如:let name: string = "coco";
boolean
:表示布尔类型,例如:let isStudent: boolean = true;
array
:表示数组类型,例如:let numbers: number[] = [1, 2, 3];
tuple
:表示元组类型,即具有固定长度和特定类型的数组,例如:let person: [string, number] = ['coco', 28];
enum
:表示枚举类型,例如:enum Color { Red, Green, Blue }; let color: Color = Color.Red;
any
:表示任意类型,即不进行类型检查,例如:let data: any = "Hello";
变量的类型推断
类型推断机制,可以根据变量的赋值来推断其类型:
let age = 28; // 推断为number类型
let name = "coco"; // 推断为string类型
let isStudent = true; // 推断为boolean类型
函数的类型声明
声明函数的参数和返回值的类型:
function add(x: number, y: number): //参数x和y均为number类型
number {//返回值也为number类型
return x + y;
}
对象的类型声明
声明对象的属性和类型:
let person: { name: string, age: number } = {//person对象具有name和age属性,分别为string类型和number类型
name: "coco",
age: 28
};
使用接口(interface)来定义对象的类型:
interface Person {
name: string;
age: number;
}
let person: Person = {
name: "coco",
age: 28
};
- 学习基本的类型注解和类型推断规则。
类型注解
通过在变量或函数参数后面使用冒号(:)加上特定类型来声明变量的类型,此方法在编译阶段就会对变量类型进行检查。
let age: number = 28;//声明了age变量为number类型,name变量为string类型
let name: string = "coco";
类型推断
TypeScript根据变量的赋值来自动推断其类型。如果变量有初始值,TypeScript会根据初始值的类型推断出变量的类型。
let age = 28; // 推断为number类型
let name = "coco"; // 推断为string类型
利用静态类型检查功能,在编译阶段发现潜在的类型错误
// 声明变量的类型
let name: string = "coco";
const age: number = 28;
// 函数参数和返回值的类型注解
function greet(name: string): void {
console.log("Hello, " + name + "!");
}
greet("coco");
基本的类型推断规则
TypeScript的类型推断遵循以下基本规则:
如果变量初始化时有明确的类型注解,则直接使用注解的类型。
如果变量初始化时没有类型注解,TypeScript会根据初始值推断出变量的类型。
如果变量的赋值表达式包含多种类型,则会推断为联合类型。
如果变量在多个地方被赋予不同类型的值,TypeScript会推断出最广泛的类型(即类型的交集)。
通过类型注解和类型推断,TypeScript可以在编译阶段发现许多潜在的类型错误,提供更好的代码提示和自动补全功能。使用适当的类型注解可以增加代码的可读性和可维护性。
但是!!!类型注解不能改变变量的原始类型,它只是在编译时进行静态类型检查。在运行时,JavaScript依然是一种动态类型的语言。
- 理解可选类型、联合类型和交叉类型等高级类型概念。
可选类型(Optional Types)
可选类型允许在变量或对象属性上设置为可能为undefined
或null
的值。并使用?
来标记可选类型:
let age: number | undefined = 28;
//age变量被声明为number | undefined类型,表示它可以是一个数字或者是undefined
let name: string | null = "coco";
//name变量被声明为string | null类型,表示它可以是一个字符串或者是null
联合类型(Union Types)
联合类型允许变量具有多个可能的类型之一。并使用|
来定义联合类型:
let value: string | number = "Hello";
//value变量被声明为string | number类型,表示它可以是一个字符串或者是一个数字
value = 10;
//在赋值时,可将其指定为字符串或数字
交叉类型(Intersection Types)
交叉类型允许将多个类型合并为一个类型。使用&
来定义交叉类:
interface A {//定义接口A
propA: number;
}
interface B {//定义接口B
propB: string;
}
type C = A & B;//合并在类型C中,使C同时具有A和B的属性
let obj: C = {//声明变量obj为C类型,同时具有propA和propB属性
propA: 10,
propB: "Hello"
};
类和接口
- 掌握使用类和接口来实现面向对象编程。
// 类和继承
class Person {
constructor(public name: string, public age: number) {}
sayHello(): void {
console.log("Hello, my name is " + this.name);
}
}
class Student extends Person {
constructor(name: string, age: number, public grade: number) {
super(name, age);
}
study(): void {
console.log(this.name + " is studying in grade " + this.grade);
}
}
const coco = new Person("coco", 28);
coco.sayHello(); // 输出:Hello, my name is coco
const pxx = new Student("pxx", 20, 14);
pxx.sayHello(); // 输出:Hello, my name is pxx
pxx.study(); // 输出:pxx is studying in grade 14
- 学习如何定义和使用接口,以实现代码的可复用性和可扩展性。
定义对象的结构和行为
interface Shape {
calculateArea(): number;
}
class Circle implements Shape {
constructor(public radius: number) {}
calculateArea(): number {
return Math.PI * this.radius ** 2;
}
}
class Rectangle implements Shape {
constructor(public width: number, public height: number) {}
calculateArea(): number {
return this.width * this.height;
}
}
const circle = new Circle(5);
console.log(circle.calculateArea()); // 输出:78.54
const rectangle = new Rectangle(4, 3);
console.log(rectangle.calculateArea()); // 输出:12
接口的可选属性和只读属性
接口的属性可以设置为可选或只读。属性使用?
进行标记,表示可以存在或不存在。只读属性使用readonly
进行标记,表示属性只能在对象初始赋值时被修改。
定义一个具有可选属性和只读属性的接口:
interface Car {
brand: string;
model?: string; // 可选属性
readonly year: number; // 只读属性
}
泛型
- 理解 TypeScript 中的泛型概念和用法。
- 学会使用泛型提高代码的灵活性和重用性。
泛型函数
使用泛型来定义函数,使其能够处理不同类型的数据。在函数名后面使用尖括号(<>)加上一个大写字母,来声明泛型类型参数:
function identity<T>(arg: T): T {//使用泛型类型参数T,并接受一个参数arg
return arg;//返回相同的类型
}
let result = identity<string>("Hello");//调用时,我们指定了具体的类型为string,函数就能处理字符串类型的数据,并返回相同的类型
泛型类
类使用泛型来增加灵活性。通过在类名后面使用尖括号加上一个大写字母来声明泛型类型参数:
//定义泛型类Stack,它可以操作任意类型的数据。
class Stack<T> {
private items: T[] = [];
push(item: T): void {
this.items.push(item);
}
pop(): T | undefined {
return this.items.pop();
}
}
//指定具体的类型为number,就可以使用push和pop方法来处理数字类型的数据
let stack = new Stack<number>();
stack.push(1);
stack.push(2);
let item = stack.pop();
泛型接口
使用泛型来定义接口:
//KeyValuePair接口使用了两个泛型类型参数K和V,表示键和值的类型
interface KeyValuePair<K, V> {
key: K;
value: V;
}
//声明pair变量,并指定其键为字符串类型,值为数字类型
let pair: KeyValuePair<string, number> = { key: "age", value: 25 };
应用:
function echo<T>(arg: T): T {
return arg;
}
const result = echo("Hello, TypeScript!"); // 类型推断为 string
console.log(result); // 输出:Hello, TypeScript!
const numbers: Array<number> = [1, 2, 3, 4, 5];
const reversedNumbers: Array<number> = numbers.reverse();
console.log(reversedNumbers); // 输出:[5, 4, 3, 2, 1]
模块化开发
- 学习如何在 TypeScript 中组织和管理模块。
使用命名空间(Namespace)
命名空间是一种将相关的代码封装到一个容器中的方式。通过使用namespace
关键字来创建命名空间。
//创建一个名为MyModule的命名空间
namespace MyModule {
//定义myFunction函数,并export关键字将它们导出
export function myFunction() {
// ...
}
//定义MyInterface接口,并使用export关键字将它们导出
export interface MyInterface {
// ...
}
}
- 熟悉模块导入和导出的语法和规则。
使用模块化语法
使用模块化语法来组织代码。使用import
和export
关键字来导入和导出模块
// 将add函数定义在math.ts文件中,并使用export关键字将其导出
export function add(x: number, y: number): number {
return x + y;
}
// 在main.ts文件中使用import关键字从math.ts文件导入add函数
import { add } from "./math";
let result = add(1, 2);
模块化开发将代码分割成独立的模块,并进行导入和导出.
// greeter.ts
export function greet(name: string): void {
console.log("Hello, " + name + "!");
}
// app.ts
import { greet } from "./greeter";
greet("coco"); // 输出:Hello, coco!