一、JS 是什么?
JavaScript(简称 JS)是一门轻量级、解释型 的脚本语言,最初由 Brendan Eich 在 1995 年为 Netscape 浏览器设计。它遵循 ECMAScript 规范,是目前 Web 开发中不可或缺的三大核心技术之一(HTML、CSS、JavaScript),主要负责网页的交互逻辑。
JS 的核心特性包括:
- 动态类型:变量的类型在运行时确定,灵活但需要谨慎处理。
- 原型继承:JS 使用原型链(prototype chain)实现对象之间的继承,与传统的类继承有所不同。
- 事件驱动:在浏览器环境中,JS 通过事件监听来响应用户操作。
- 单线程 + 事件循环:JS 主线程是单线程的,但通过事件循环(Event Loop)和回调队列实现异步操作。
JS 不仅可以运行在浏览器中,还可以运行在服务器端(通过 Node.js)、移动应用(React Native、Flutter 等)、桌面应用(Electron)等环境中。
二、内联样式(head 和 body 中)和外联样式
在 HTML 中,引入 CSS 样式主要有三种方式:内联样式 、内部样式表 和外部样式表。
1. 内联样式
直接写在 HTML 元素的 style 属性中,优先级最高。适用于少量或一次性样式,但不易维护。
html
<p style="color: red; font-size: 16px;">这是一段红色文字</p>
2. 内部样式表
写在 HTML 文件的 <head> 标签内,使用 <style> 标签包裹。适合单个页面的样式管理。
html
<head>
<style>
p { color: blue; }
</style>
</head>
3. 外部样式表
将样式写在一个独立的 .css 文件中,通过 <link> 标签引入。这种方式的优点在于:
- 可以实现样式复用,多个 HTML 文件共用同一个 CSS 文件。
- 便于团队协作和代码维护。
- 浏览器可以缓存 CSS 文件,加快页面加载。
html
<head>
<link rel="stylesheet" href="styles.css" />
</head>
三、var、let 和 const
在 JS 中,var、let 和 const 是声明变量的三种关键字,它们之间的差异主要体现在作用域、提升行为和可变性三个方面。
| 关键字 | 作用域 | 变量提升 | 是否可重新赋值 | 是否必须初始化 |
|---|---|---|---|---|
var |
函数作用域 | 提升(初始值为 undefined) | 可以 | 否 |
let |
块级作用域 | 提升但有「暂时性死区」 | 可以 | 否 |
const |
块级作用域 | 提升但有「暂时性死区」 | 不可以 | 是 |
实际建议 :优先使用 const,只有在需要重新赋值时使用 let,尽量避免使用 var 以避免变量提升和作用域混乱带来的问题。
javascript
var x = 1; // 函数作用域,可以重复声明
let y = 2; // 块级作用域,不允许重复声明
const z = 3; // 块级作用域,声明时必须赋值,且不可重新赋值
if (true) {
var x = 10; // 覆盖外部的 x
let y = 20; // 只在 if 块内有效
const z = 30; // 只在 if 块内有效
}
console.log(x); // 10(被内部 var 覆盖)
console.log(y); // 2(外部 let 不受影响)
console.log(z); // 3(外部 const 不受影响)
四、undefined 和 null
undefined 和 null 都表示「无值」,但在语义和使用场景上有明显区别:
- undefined :表示变量已声明但未赋值,或函数没有返回值,或对象属性不存在。它是 JS 引擎自动赋予的默认值。
- null :表示一个空对象引用,通常由开发者主动赋值,用于表示「此处应该有一个对象,但目前没有」。
在进行相等性比较时需要注意:
javascript
console.log(undefined == null); // true(宽松相等)
console.log(undefined === null); // false(严格相等,类型不同)
console.log(typeof undefined); // "undefined"
console.log(typeof null); // "object"(历史遗留的 bug)
实际开发中,建议使用 null 表示「有意为空」,使用 undefined 来检查变量是否已初始化。
五、alert、confirm、prompt
这三种都是浏览器提供的内置对话框,用于与用户进行简单的交互和通知。
1. alert(警告框)
弹出一个提示信息,只有一个「确定」按钮。通常用于通知用户某些操作的结果。
javascript
alert("操作成功!");
2. confirm(确认框)
弹出一个带有「确定」和「取消」按钮的对话框,返回布尔值。常用于确认删除、退出等操作。
javascript
if (confirm("确定要删除这条记录吗?")) {
console.log("用户点击了确定");
} else {
console.log("用户点击了取消");
}
3. prompt(输入框)
弹出一个带有文本输入框的对话框,返回用户输入的字符串(点击取消则返回 null)。
javascript
const name = prompt("请输入你的名字:");
if (name !== null && name !== "") {
alert("你好," + name + "!");
}
需要注意的是,这些弹窗会阻塞页面的执行,并且样式受浏览器控制,无法自定义样式。现代开发中多使用 Modal(模态框)组件替代。
六、JS 的函数
函数是 JS 中的一等公民,可以通过多种方式定义和调用,是组织代码、实现复用的核心机制。
1. 函数定义方式
JS 提供了多种定义函数的方法:
javascript
// 函数声明
function add(a, b) {
return a + b;
}
// 函数表达式
const multiply = function(a, b) {
return a * b;
};
// 箭头函数(ES6)
const subtract = (a, b) => a - b;
// 立即执行函数(IIFE)
(function() {
console.log("立即执行");
})();
2. 参数和返回值
函数可以接受任意数量的参数(包括不传或少传),如果参数未被传入,则为 undefined。函数默认返回 undefined,除非显式使用 return 语句。
3. 函数也是对象
函数本身也是对象,可以有属性和方法,也可以作为参数传递给其他函数(回调函数),或作为另一个函数的返回值(高阶函数)。
七、JS 的事件:事件绑定的三种方式
事件是 JS 与用户交互的核心机制。绑定事件处理函数主要有以下三种方式:
1. HTML 属性绑定
直接在 HTML 标签上使用事件属性(如 onclick),写法简单但不推荐------因为混入了 HTML 和 JS,不利于维护。
html
<button onclick="handleClick()">点击</button>
2. DOM 属性绑定
通过 JS 获取 DOM 元素后,直接给事件属性赋值。缺点是同一个事件只能绑定一个处理函数,后绑定的会覆盖前面的。
javascript
const btn = document.getElementById("myBtn");
btn.onclick = function() {
console.log("点击了按钮");
};
3. addEventListener(推荐)
使用 addEventListener 方法可以绑定多个处理函数 ,并且可以精确控制事件在捕获阶段 或冒泡阶段执行(第三个参数)。
javascript
const btn = document.getElementById("myBtn");
btn.addEventListener("click", function() {
console.log("第一个处理函数");
});
btn.addEventListener("click", function() {
console.log("第二个处理函数");
});
// 移除事件监听
btn.removeEventListener("click", handler);
八、DOM
DOM(Document Object Model,文档对象模型)是浏览器将 HTML 文档解析为一个由节点和对象组成的树形结构,编程语言(如 JS)可以操作这个树来动态改变页面的内容、结构和样式。
常用的 DOM 操作方法包括:
- 获取元素 :
document.getElementById()、document.querySelector()、document.querySelectorAll()等。 - 创建元素 :
document.createElement()。 - 插入元素 :
parent.appendChild(child)、parent.insertBefore(newNode, referenceNode)。 - 修改属性和样式 :
element.setAttribute()、element.style、element.classList。 - 删除元素 :
parent.removeChild(child)或element.remove()。
javascript
// 创建一个新的 p 元素并添加到 body 中
const newP = document.createElement("p");
newP.textContent = "这是通过 JS 动态创建的段落";
document.body.appendChild(newP);
九、innerHTML 和 innerText
innerHTML 和 innerText 都可以用来读取或修改 HTML 元素的内容,但它们的行为有本质区别:
| 属性 | 读取内容 | 写入内容 | 是否解析 HTML |
|---|---|---|---|
innerHTML |
返回元素内部的 HTML 字符串 | 可以写入 HTML 标签,会被解析渲染 | 是 |
innerText |
返回元素内部可见的纯文本 | 写入的内容会被当作纯文本处理 | 否 |
实际开发中的重要区别:
- innerHTML 可以动态插入 HTML 结构,但如果内容来自用户输入,可能存在XSS 安全风险。
- innerText 只处理文本,更安全,但无法插入 HTML 标签。
- 还有一个
textContent属性,与 innerText 类似但会返回所有文本(包括隐藏元素的文本),且性能更好。
javascript
const element = document.getElementById("demo");
element.innerHTML = "<strong>加粗文字</strong>"; // 渲染为加粗文字
element.innerText = "<strong>加粗文字</strong>"; // 显示原始标签文本