本文转载自:https://fangcaicoding.cn/article/53
大家好!我是方才,目前是8人后端研发团队的负责人,拥有6年后端经验&3年团队管理经验,截止目前面试过近200位候选人,主导过单表上10亿、累计上100亿数据量级的业务系统的架构和核心编码。
“学编程,一定要系统化” 是我一直坚持的学习之道。目前正在系统化分享从零到一的全栈编程入门以及项目实战教程。
无论你是编程新手,还是有经验的开发者,我都愿意与你分享我的学习方法、项目实战经验,甚至提供学习路线制定、简历优化、面试技巧等深度交流服务。
我创建了一个编程学习交流群(扫码关注后即可加入),秉持“一群人可以走得更远”的理念,期待与你一起 From Zero To Hero!
茫茫人海,遇见即是缘分!希望这篇文章对你有所帮助!
JavaScript入门-下
函数
函数的定义与调用
函数是一段可复用的代码,可以根据需要调用多次。
function greet(name) {
return "Hello, " + name;
}
let message = greet("Alice");
console.log(message); // 输出 "Hello, Alice"
函数的参数与返回值
函数可以接收参数并返回一个值。
function add(a, b) {
return a + b;
}
let sum = add(5, 10);
console.log(sum); // 输出 15
函数表达式
函数可以作为表达式赋值给变量,这种函数称为函数表达式。
let multiply = function(a, b) {
return a * b;
};
console.log(multiply(3, 4)); // 输出 12
箭头函数(ES6)
箭头函数是一种更简洁的函数定义方式,常用于简短的函数。
let divide = (a, b) => a / b;
console.log(divide(10, 2)); // 输出 5
如果箭头函数有多个语句,可以用 {}
包裹,并需要显式 return
。
let square = (x) => {
let result = x * x;
return result;
};
console.log(square(5)); // 输出 25
匿名函数与回调函数
匿名函数没有函数名,常用于事件处理或回调函数。
setTimeout(function() {
console.log("1秒后执行此函数");
}, 1000); // 1秒后执行
递归函数
递归函数是调用自身的函数,常用于解决分治问题或递归结构。
function factorial(n) {
if (n === 1) {
return 1;
}
return n * factorial(n - 1); // 递归调用自身
}
console.log(factorial(5)); // 输出 120
ES6 新特性(了解即可)
ES6(ECMAScript 2015)为 JavaScript 带来了很多重要的新特性,极大地提高了代码的简洁性和可维护性。
块级作用域(let
和 const
)
-
let
和const
引入了块级作用域,避免了var
的变量提升和作用域问题。 -
let
:声明变量,可以重新赋值。 -
const
:声明常量,不能重新赋值。
let age = 30;
const name = "Alice";
// name = "Bob"; // 错误:无法重新赋值常量
模板字符串(Template Literals)
模板字符串使用反引号(`
)定义,允许在字符串中嵌入表达式,并支持多行字符串。
let name = "Alice";
let greeting = `Hello, ${name}!`; // 使用 ${} 进行插值
console.log(greeting); // 输出 "Hello, Alice!"
let multiLine = `这是一行
这是另一行`;
console.log(multiLine);
解构赋值(Destructuring)
解构赋值可以从数组或对象中提取值,并将其赋给变量。
数组解构
let [first, second] = [1, 2];
console.log(first); // 输出 1
console.log(second); // 输出 2
对象解构
let person = { name: "Alice", age: 25 };
let { name, age } = person; // 解构对象
console.log(name); // 输出 "Alice"
console.log(age); // 输出 25
扩展运算符(Spread Operator)
扩展运算符 ...
可以将数组或对象展开为单独的元素。
数组的扩展运算符
let arr1 = [1, 2, 3];
let arr2 = [...arr1, 4, 5]; // 展开 arr1 并追加新元素
console.log(arr2); // 输出 [1, 2, 3, 4, 5]
对象的扩展运算符
let obj1 = { a: 1, b: 2 };
let obj2 = { ...obj1, c: 3 }; // 展开 obj1 并添加新属性
console.log(obj2); // 输出 { a: 1, b: 2, c: 3 }
箭头函数
箭头函数是 ES6 中引入的简洁语法,特别适合简短的函数表达式。它没有自己的 this
,会捕获其外部函数的 this
值。
let sum = (a, b) => a + b;
console.log(sum(3, 5)); // 输出 8
默认参数
函数参数可以设置默认值,当调用时不提供对应的参数时,默认值会生效。
function greet(name = "Guest") {
console.log(`Hello, ${name}!`);
}
greet(); // 输出 "Hello, Guest!"
greet("Alice"); // 输出 "Hello, Alice!"
for...of
循环
for...of
循环可以遍历数组或其他可迭代对象。
let colors = ["red", "green", "blue"];
for (let color of colors) {
console.log(color); // 输出 "red", "green", "blue"
}
Promise
对象
Promise
用于处理异步操作,避免回调地狱。
let promise = new Promise((resolve, reject) => {
let success = true;
if (success) {
resolve("操作成功");
} else {
reject("操作失败");
}
});
promise.then((message) => {
console.log(message); // 操作成功
}).catch((error) => {
console.log(error);
});
类(Class)
ES6 引入了 class
语法,用于更清晰地定义对象的构造函数和方法。
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`);
}
}
let person1 = new Person("Alice", 25);
person1.greet(); // 输出 "Hello, my name is Alice and I'm 25 years old."
好的,我们继续详细讲解 事件处理 和 JavaScript 与 HTML 整合,并提供相应的代码示例:
事件处理(了解即可)
这部分的了解,可以直接使用的在线编辑器,允许示例代码,感受相关的功能即可。
在线编辑器链接:https://www.runoob.com/try/try.php?filename=tryhtml_intro
事件处理是前端开发中非常重要的一部分。它允许我们捕获用户的操作(如点击、输入、提交等),并做出响应。
常见的事件类型
-
点击事件(
click
):当用户点击元素时触发。 -
键盘事件(
keydown
、keyup
):当用户按下或释放键盘按键时触发。 -
鼠标事件(
mouseover
、mouseout
):当鼠标悬停或离开元素时触发。 -
表单事件(
submit
、change
、input
):当表单提交、元素内容改变或输入时触发。
事件处理的基本用法
我们可以通过 HTML 的属性(如 onclick
)或 JavaScript 的 addEventListener
方法来绑定事件处理函数。
1. 通过 HTML 属性绑定事件
<button onclick="alert('按钮被点击')">点击我</button>
2. 通过 JavaScript 绑定事件
更好的方式是通过 JavaScript 使用 addEventListener
来添加事件监听器。
<button id="myButton">点击我</button>
<script>
let button = document.getElementById("myButton");
// 添加点击事件监听器
button.addEventListener("click", function() {
alert("按钮被点击");
});
</script>
事件对象(event
)
当事件被触发时,浏览器会创建一个事件对象 event
,它包含了事件相关的信息(如鼠标位置、按键状态等)。
示例:获取点击位置
<button id="positionButton">点击获取鼠标位置</button>
<script>
let button = document.getElementById("positionButton");
button.addEventListener("click", function(event) {
let x = event.clientX;
let y = event.clientY;
alert(`你点击的位置: X = ${x}, Y = ${y}`);
});
</script>
事件冒泡与捕获
事件有两个传播阶段:冒泡(从内到外)和捕获(从外到内)。默认情况下,事件处理是在冒泡阶段执行的,但你也可以选择在捕获阶段处理。
停止事件传播
可以使用 event.stopPropagation()
来阻止事件进一步传播。
<div id="outerDiv" style="width: 200px; height: 200px; background-color: lightblue;">
外部DIV
<div id="innerDiv" style="width: 100px; height: 100px; background-color: lightgreen;">
内部DIV
</div>
</div>
<script>
let outerDiv = document.getElementById("outerDiv");
let innerDiv = document.getElementById("innerDiv");
outerDiv.addEventListener("click", function() {
alert("外部DIV被点击");
});
innerDiv.addEventListener("click", function(event) {
alert("内部DIV被点击");
event.stopPropagation(); // 阻止事件冒泡
});
</script>
点击内部 DIV
时,只有内部的事件会触发,外部的不会触发。
事件委托
事件委托是一种优化事件处理的方法,它通过将事件监听器绑定到父元素上,利用事件冒泡来捕获子元素的事件。这样可以减少对多个子元素的事件绑定,尤其适用于动态创建的元素。
示例:事件委托
<ul id="list">
<li>项 1</li>
<li>项 2</li>
<li>项 3</li>
</ul>
<script>
let list = document.getElementById("list");
list.addEventListener("click", function(event) {
if (event.target.tagName === "LI") {
alert("你点击了 " + event.target.innerText);
}
});
</script>
无论你点击哪个 li
,都能捕获到点击事件,且只需要给父元素 ul
添加一次事件监听器。
JavaScript 与 HTML 整合(了解即可)
JavaScript 可以与 HTML 和 CSS 紧密结合,为网页提供交互功能。JavaScript 可以操作 DOM(文档对象模型)来动态修改页面内容和样式。
操作 DOM(Document Object Model)
获取 DOM 元素
你可以通过各种方法来获取 DOM 元素:
-
getElementById
:通过元素的id
获取。 -
getElementsByClassName
:通过类名获取。 -
querySelector
:通过 CSS 选择器获取(第一个匹配的元素)。 -
querySelectorAll
:通过 CSS 选择器获取所有匹配的元素。
<p id="myParagraph">这是一个段落。</p>
<p class="text">这是另一个段落。</p>
<script>
// 通过 ID 获取元素
let paragraph = document.getElementById("myParagraph");
console.log(paragraph.innerText); // 输出 "这是一个段落。"
// 通过类名获取元素
let textElements = document.getElementsByClassName("text");
console.log(textElements[0].innerText); // 输出 "这是另一个段落。"
// 使用 querySelector 获取元素
let firstParagraph = document.querySelector("p");
console.log(firstParagraph.innerText); // 输出 "这是一个段落。"
</script>
修改 DOM 内容
你可以使用 innerText
或 innerHTML
来修改元素的文本或 HTML 内容。
<p id="textElement">初始内容</p>
<script>
let textElement = document.getElementById("textElement");
textElement.innerText = "修改后的文本";
textElement.innerHTML = "<strong>加粗的文本</strong>";
</script>
修改样式
可以通过 style
属性来修改元素的 CSS 样式,或通过添加/删除 CSS 类来改变样式。
<p id="styleElement" style="color: blue;">这是一个蓝色文本。</p>
<script>
let styleElement = document.getElementById("styleElement");
// 修改样式
styleElement.style.color = "red"; // 变为红色
// 添加 CSS 类
styleElement.classList.add("highlight");
</script>
<style>
.highlight {
background-color: yellow;
}
</style>
创建和删除 DOM 元素
你可以动态创建和删除 HTML 元素。
创建新元素
<div id="container"></div>
<script>
let container = document.getElementById("container");
// 创建一个新的 p 元素
let newParagraph = document.createElement("p");
newParagraph.innerText = "这是新添加的段落。";
// 将新元素添加到 container 中
container.appendChild(newParagraph);
</script>
删除元素
let container = document.getElementById("container");
// 移除子元素
container.removeChild(newParagraph);
事件驱动的页面交互示例
以下是一个简单的例子,演示如何结合 JavaScript 与 HTML 进行交互,通过点击按钮来动态修改网页内容和样式。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>页面交互示例</title>
</head>
<body>
<h1>点击按钮修改页面</h1>
<p id="content">这是一段可修改的内容。</p>
<button id="changeButton">修改内容</button>
<script>
let button = document.getElementById