JavaScript的初步学习
目录
JavaScript简介
主要特点
主要用途
JavaScript的基本特性
JavaScript的引入方式
1. 内联方式 (Inline JavaScript)
2. 内部方式 (Internal JavaScript / Embedded JavaScript)
3. 外部方式 (External JavaScript)
JavaScript的语法介绍
1.书写语法
2.输出语句
3.变量
(1)变量的声明关键词
a. var
b. let
c. const
(2) 变量的命名规则
(3) 变量的作用域
(4) 变量的提升(Hoisting)
4.数据类型
(1)基本数据类型(原始类型)
a. 数字(Number)
b. 字符串(String)
c. 布尔值(Boolean)
d. undefined
e. null
f. Symbol(符号)
(2)复杂数据类型(引用类型)
a. 对象(Object)
b. 数组(Array)
c. 特殊对象:Date, RegExp, Error等
(3)类型转换
a. 转字符串
b. 转数字
c. 转布尔值
(4)值得注意的细节
a. typeof运算符
b.instanceof
5.运算符
6.流程控制语句
7.函数
(1) 函数的定义方式
a.函数声明(Function Declaration)
b.函数表达式(Function Expression)
c.箭头函数(Arrow Function)
(2)函数参数的语法和细节
a. 默认参数(Default Parameters)
b. 剩余参数(Rest Parameters)
c. 参数解构(Destructuring)
(3) 函数作用域与闭包
a. 作用域
b. 闭包
(4)函数的this绑定规律
a. 普通函数
b. 箭头函数
c. 更复杂的绑定规则
(5)函数的返回值
(6) 生成器函数(Generator Functions)
8.对象
(1)常用对象
(2)自定义对象
a. 对象的创建方式
对象字面量(Object Literal)- 最常用
new Object() 构造函数
构造函数(Constructor Function)- 创造类实例的“模板”
使用原型(Prototype)优化构造函数 - 共享方法
ES6 class 语法 - 现代JS推荐的面向对象方式
b. 访问和修改对象属性/方法
点表示法(Dot Notation)
方括号表示法(Bracket Notation)
c. 删除对象属性
d. 检查属性是否存在
in 运算符
hasOwnProperty() 方法
e. 遍历对象属性
for...in 循环
Object.keys()
Object.values()
Object.entries()
f. 短属性名和短方法名(ES6)
g. 计算属性名(Computed Property Names)(ES6)
9.JSON
(1)什么是JSON
(2)JSON的语法规则
a.基本结构
b.JSON对象(Object)
c. JSON数组(Array)
d. 数值(Number)
e. 字符串(String)
f. 布尔值(Boolean)
g. null值
h. 不能出现
(3)在JavaScript中操作JSON
a.转换为JSON字符串:JSON.stringify
b. 解析JSON字符串:JSON.parse
(4)扩展:自定义对象转JSON的细节
10.BOM
(1)什么是BOM?
(2)BOM的核心对象和功能
(3)BOM的常用对象及使用细节
a. window对象
b. location对象
c. history对象
e. screen对象
f. 定时器函数
(4)弹窗相关函数
(5)浏览器宽高与窗口操作
a. innerWidth 和 innerHeight
b. outerWidth 和 outerHeight
c. resize事件
d. 弹出新窗口(或标签页)
e. 控制窗口大小与位置
11.DOM
(1)什么是DOM
(2)DOM的基本结构
(3)常用的DOM操作语法和细节
a. 访问元素
b. 修改元素
c. 创建新元素
d. 删除元素
e. 事件绑定
f. 其他常用操作
(4)DOM操作的细节注意点
(5)示例
JavaScript简介
JavaScript(简称JS)是一种广泛使用的动态脚本语言,主要用于网页开发,赋予网页动态交互功能。它由网景公司(Netscape)的布兰登·艾奇(Brendan Eich)在1995年开发,最初名为LiveScript,后来改名为JavaScript。
主要特点
-
客户端脚本:主要在浏览器中执行,使网页具有动态效果和交互能力(如表单验证、动画、实时更新内容等)。
-
动态类型:变量类型在运行时确定,不需要预定义。
-
弱类型:类型转换自动进行,使用灵活。
-
事件驱动:响应用户操作(点击、悬停、提交等)。
-
多范式:支持面向对象、函数式、命令式编程。
主要用途
-
网页交互:实现按钮点击、表单验证、动画效果。
-
网页开发框架:如React、Vue、Angular。
-
服务器端编程:通过Node.js,JavaScript还能在服务器执行。
-
移动应用:如React Native。
-
桌面应用、游戏开发:通过特殊平台和引擎实现。
JavaScript的基本特性
-
简洁灵活的语法:类似C、Java的语法,但比它们简单易用。
-
原生支持事件处理:可以直接在HTML或JavaScript中绑定事件。
-
DOM操作:可以直接操作网页结构(Document Object Model)。
-
异步编程:支持Promise、async/await等技术,方便处理异步任务。
JavaScript的引入方式
1. 内联方式 (Inline JavaScript)
概念: 将JavaScript代码直接作为HTML标签的属性值使用。通常用于处理特定的事件,例如点击按钮时执行一段JS代码。
优点:
-
简单直接,适用于非常短小、针对特定元素的逻辑。
-
无需额外的文件或
<script>
标签。
缺点:
-
极其不推荐! 严重违反了结构(HTML)、样式(CSS)、行为(JavaScript)分离的原则。
-
代码可读性差,难以维护。
-
代码复用性差。
-
增加了HTML文件的体积。
<!DOCTYPE html>
<html>
<head><title>内联JavaScript示例</title>
</head>
<body><button onclick="alert('你点击了我,内联方式!');">点击我</button><a href="#" onmouseover="this.style.color='red';"onmouseout="this.style.color='black';">鼠标悬停</a>
</body>
</html>
2. 内部方式 (Internal JavaScript / Embedded JavaScript)
概念: 将JavaScript代码放置在HTML文件的<script>
标签内部。<script>
标签可以放在HTML文档的<head>
部分,也可以放在<body>
部分。
优点:
-
代码都在一个HTML文件中,方便小型项目或单页面应用。
-
避免了额外的HTTP请求。
缺点:
-
不利于代码复用。如果多个HTML页面需要相同的JavaScript代码,就需要复制代码。
-
增加了HTML文件的体积,下载时需要加载整个JS代码。
-
如果JS代码量很大,可能会阻塞页面内容的渲染(尤其是放在
<head>
里)。
建议放置位置: 通常推荐将 <script>
标签放置在 <body>
标签的闭合标签 </body>
之前。这样做的原因是:
-
避免阻塞渲染: 浏览器在解析HTML时,遇到
<script>
标签会暂停HTML的解析和渲染,转而去下载和执行JavaScript代码。如果JavaScript在页面的顶部(<head>
中)且代码量较大,用户可能会看到空白页面的时间延长。 -
确保DOM可用: JavaScript代码通常需要操作HTML元素(DOM)。如果JavaScript在元素加载之前就执行,可能会找不到要操作的元素,导致错误。将JavaScript放置在
</body>
之前,可以保证它执行时,页面上的所有HTML元素已经被浏览器解析并创建为DOM树。
<!DOCTYPE html>
<html lang="zh-CN">
<!-- HTML文档的语言设置为中文 -->
<head><!-- 字符集为UTF-8 --><meta charset="UTF-8"><!-- 设置浏览器兼容性 --><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>内部JavaScript示例</title><script>// 这是放置在 head 标签内的 JavaScript 代码function showHeadMessage() {console.log("这是来自 head 标签内的 JavaScript。");}</script>
</head>
<body><h1>内部JavaScript</h1><p id="myParagraph">这是一个段落。</p><button onclick="changeText()">点击改变段落</button><script>// 这是放置在 body 标签末尾的 JavaScript 代码function changeText() {document.getElementById("myParagraph").innerText = "段落内容已被JavaScript改变!";}// 页面加载完成后执行window.onload = function() {showHeadMessage(); // 调用 head 中的函数console.log("页面已加载完成,这是来自 body 标签末尾的 JavaScript。");};</script>
</body>
</html>
3. 外部方式 (External JavaScript)
概念: 将JavaScript代码单独保存在一个.js
文件中,然后在HTML文件中通过<script>
标签的 src
属性引入。
优点:
-
最推荐的方式! 实现了结构、样式、行为的完全分离,代码清晰,易于维护。
-
代码复用性高: 多个HTML页面可以引用同一个
.js
文件,避免重复编写代码。 -
浏览器缓存:
.js
文件可以被浏览器缓存,当用户再次访问或访问其他页面时,无需重新下载,加快页面加载速度。 -
优化加载性能:
-
可以使用
defer
属性:脚本会延迟到文档解析完成后才执行,但会按照它们在文档中出现的顺序执行。不会阻塞HTML解析。 -
可以使用
async
属性:脚本会异步加载,并在加载完成后立即执行,不保证执行顺序,也会阻塞HTML解析(但只在脚本下载期间)。 -
推荐:将
<script>
标签放在</body>
闭合标签之前。
-
缺点:
-
增加了一个HTTP请求(但可以通过浏览器缓存弥补)。
// script.js
function sayHello() {alert("你好,这是来自外部JavaScript文件!");
}
function updateDiv() {document.getElementById("messageDiv").innerText = "外部JS已修改此内容。";
}
// 页面加载完成后执行
window.onload = function() {console.log("外部JavaScript文件已加载并执行。");
};
<!DOCTYPE html>
<html lang="zh-CN">
<head><!-- 字符集为UTF-8 --><meta charset="UTF-8"><!-- 设置浏览器兼容性 --><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>外部JavaScript示例</title><!-- 推荐使用 defer 或放在 body 底部 --><script src="script.js" defer></script>
</head>
<body><h1>外部JavaScript</h1><p>这是来自HTML页面的内容。</p><div id="messageDiv">原始内容</div><button onclick="sayHello()">点击问候</button><button onclick="updateDiv()">更新内容</button>
</body>
</html>
JavaScript的语法介绍
1.书写语法
2.输出语句
3.变量
(1)变量的声明关键词
JavaScript中声明变量主要使用三种关键词:var
、let
和const
。这三者在作用域、可变性等方面存在差异。
a. var
-
最早的变量声明方式。
-
作用域为函数作用域(函数内部有效,函数外面不可见);
-
可以重复声明同一变量,后声明会覆盖前面。
b. let
-
ES6(ECMAScript 2015)引入。
-
作用域为块作用域(比如在
if
、for
、while
块内有效); -
不允许重复声明同一变量。
c. const
-
也是ES6引入。
-
作用域为块作用域;
-
必须初始化,声明后不可再赋值;
-
对于对象和数组,虽然引用不可变,但对象内容还是可变的。
(2) 变量的命名规则
-
只能以字母、
$
、_
开头; -
后续可以使用字母、数字、
$
、_
; -
不能使用JavaScript关键字(如
if
,var
,function
等)作为变量名; -
推荐命名具有描述性(语义清晰)。
(3) 变量的作用域
-
var
声明的变量:函数作用域或全局作用域(如果在函数外部声明) -
let
和const
声明的变量:块作用域(例如在if
、for
、while
内有效)
(4) 变量的提升(Hoisting)
-
var
声明的变量会提升:变量声明会被提升到作用域顶部,但赋值不会。 -
let
和const
不会提升,会在块内形成“暂时性死区(TDZ)”,访问会报错。
console.log(x); // undefined,因为var会提升声明
var x = 5;console.log(y); // 报错:Cannot access 'y' before initialization
let y = 10;console.log(z); // 报错:Cannot access 'z' before initialization
const z = 15;
4.数据类型
(1)基本数据类型(原始类型)
a. 数字(Number)
-
表示整数和浮点数。
-
JavaScript中的数字采用双精度浮点(IEEE 754标准)。
-
特殊值:
Infinity
,-Infinity
,NaN
(非数字)
let integerNum = 42; // 整数
let floatNum = 3.1415; // 浮点数
let infinity = Infinity; // 正无穷
let nanValue = NaN; // 非数字
注意:NaN
表示“非数值”,且NaN
本身不等于任何值,包括自己。
console.log(NaN === NaN); // false
console.log(isNaN(NaN)); // true
b. 字符串(String)
-
用单引号
''
或双引号""
(也支持反引号 -
支持转义字符和模板字符串。
let str1 = 'Hello';
let str2 = "World";
let str3 = `Hello, ${str2}!`; // 模板字符串,支持插值
c. 布尔值(Boolean)
-
只有两个值:
true
和false
。
d. undefined
-
表示变量未定义或未赋值。
e. null
-
表示“空值”,需要显式赋值。
f. Symbol(符号)
-
在ES6引入。
-
用于创建唯一的标识符。
const sym1 = Symbol('foo');
const sym2 = Symbol('foo');
console.log(sym1 === sym2); // false,符号唯一
(2)复杂数据类型(引用类型)
a. 对象(Object)
-
键值对集合,属性名为字符串(或Symbol),值可以为任何类型。
-
字面量定义
let obj = {name: 'Alice',age: 25,greet: function() { return 'Hello'; }
};
b. 数组(Array)
-
数对象的特殊类型,存储有序元素。
let arr = [1, 2, 3, 'a', true];
c. 特殊对象:Date
, RegExp
, Error
等
let dateNow = new Date();
let regex = /ab+c/;
(3)类型转换
JavaScript会在需要时自动进行类型转换(隐式转换),也可以手动转换。
a. 转字符串
String(123); // '123'
(123).toString(); // '123'
b. 转数字
Number('456'); // 456
parseInt('123', 10); // 123
parseFloat('3.14'); // 3.14
parseInt('12abc'); //12
parseInt('abc'); //NaN
c. 转布尔值
Boolean(0); // false
Boolean(''); // false
Boolean('hello'); // true
Boolean(undefined); // false
注意: 以下值在转换为布尔值时为false
,称为“假值”或“false值”:
-
false
-
0
-
-0
-
0n
(BigInt零) -
null
-
undefined
-
NaN
-
空字符串
''
其他值为真(true)。
(4)值得注意的细节
a. typeof
运算符
用来判断变量的数据类型。
typeof 123; // 'number'
typeof 'hello'; // 'string'
typeof true; // 'boolean'
typeof undefined; // 'undefined'
typeof null; // 'object'(这是一个历史遗留问题,null实际上是原始类型)
typeof Symbol('foo'); // 'symbol'
typeof {a:1}; // 'object'
typeof [1,2,3]; // 'object'(数组也是对象)
typeof function(){}; // 'function'(函数也是对象的一种)
b.instanceof
判断对象是否是某个类的实例。
let arr = [1,2,3];
console.log(arr instanceof Array); // true
console.log({} instanceof Object); // true
5.运算符
6.流程控制语句
和Java相近。
7.函数
(1) 函数的定义方式
a.函数声明(Function Declaration)
function 函数名(参数列表) {// 函数体
}
特点:
-
函数会被提升(hoisted),可以在声明之前调用。
-
适合定义在代码顶层或块内的标准函数。
b.函数表达式(Function Expression)
const func = function(参数) {// 函数体
};
特点:
-
不会被提升,只能在声明后使用。
-
通常用作回调函数。
c.箭头函数(Arrow Function)
const func = (参数) => {// 函数体
};
特点:
-
语法简洁,尤其适合写短函数。
-
不绑定自己的
this
,常用于回调或匿名函数。
(2)函数参数的语法和细节
a. 默认参数(Default Parameters)
function greet(name='Guest') {console.log('Hello, ' + name);
}
greet(); // 'Hello, Guest'
b. 剩余参数(Rest Parameters)
收集多余参数为数组:
function sum(...numbers) {return numbers.reduce((acc, curr) => acc + curr, 0);
}
console.log(sum(1, 2, 3, 4)); // 10
c. 参数解构(Destructuring)
解构数组或对象参数:
function display({name, age}) {console.log(name, age);
}
display({name: 'Alice', age: 30});
(3) 函数作用域与闭包
a. 作用域
-
函数定义的变量在函数内部有效,外部不可访问(除非返回或传递)。
-
函数内部可以访问外部作用域。
b. 闭包
-
函数配合其定义环境形成闭包,能“记住”当时的作用域。
function outer() {let count = 0;return function inner() {count++;console.log(count);}
}
const increment = outer();
increment(); // 1
increment(); // 2
(4)函数的this
绑定规律
a. 普通函数
-
在严格模式(
'use strict'
)下,this
为undefined
。 -
在非严格模式下,
this
指向全局对象(浏览器window
)。
function show() {console.log(this);
}
show(); // 在非严格模式:window;严格模式下:undefined
b. 箭头函数
-
没有自己的
this
,继承自定义声明时所在的作用域。
const obj = {value: 42,getValue: function() {const arrowFunc = () => this.value;return arrowFunc();}
};
console.log(obj.getValue()); // 42
c. 更复杂的绑定规则
-
使用
call
、apply
、bind
可以强制指定this
。
const obj = {name: 'Bob'};
function showName() {console.log(this.name);
}
showName.call(obj); // 'Bob'
(5)函数的返回值
-
默认返回
undefined
。 -
使用
return
语句返回值。 -
函数可以返回任何类型的数据。
注意:
-
一旦遇到
return
,函数立即结束。 -
可以返回对象、数组、函数等。
(6) 生成器函数(Generator Functions)
-
使用
function*
定义。 -
产生可迭代的值。
function* gen() {yield 1;yield 2;yield 3;
}
const iterator = gen();
console.log(iterator.next()); // { value: 1, done: false }
8.对象
(1)常用对象
(2)自定义对象
在JavaScript中,对象是键值对
的无序集合。键(key)是字符串(或Symbol),值(value)可以是任何数据类型(包括原始类型、其他对象、函数等)。
a. 对象的创建方式
对象字面量(Object Literal)- 最常用
这是创建对象最简单、最常用的方式。
// 语法:
let objectName = {key1: value1,key2: value2,// ...
};// 示例:
let person = {name: "Alice", // 属性(property)age: 30, // 属性isStudent: false, // 属性greet: function() { // 方法(method)console.log("Hello, my name is " + this.name);}
};
细节:
-
属性名可以是标识符(不带引号,如
name
),也可以是字符串(带引号,如"user-id"
)。如果属性名是无效的标识符(如包含连字符、空格或数字开头),则必须用引号。 -
属性值可以是任何数据类型。
-
方法是值为函数的属性。
-
this
关键字在对象方法中指向当前对象本身。
new Object()
构造函数
不常用,但也是一种创建方式。
let person = new Object();
person.name = "Bob";
person.age = 25;
person.greet = function() {console.log("Hi, I'm " + this.name);
};
构造函数(Constructor Function)- 创造类实例的“模板”
用于创建具有相同属性和方法的多个对象。
// 语法:
function ConstructorName(param1, param2) {this.property1 = param1;this.property2 = param2;this.method = function() {// ...};
}// 示例:
function Person(name, age) {this.name = name;this.age = age;this.greet = function() {console.log("Hello, my name is " + this.name + " and I am " + this.age + " years old.");};
}// 使用 new 关键字创建实例
let person1 = new Person("Charlie", 40);
let person2 = new Person("Diana", 28);person1.greet(); // Hello, my name is Charlie and I am 40 years old.
person2.greet(); // Hello, my name is Diana and I am 28 years old.
细节:
-
函数名通常首字母大写(约定)。
-
this
关键字在构造函数中指代新创建的实例。 -
必须使用
new
关键字来调用构造函数,否则this
会指向全局对象(非严格模式下)。 -
每个实例都会有自己的
greet
方法,这可能会造成内存浪费(因为方法相同)。
使用原型(Prototype)优化构造函数 - 共享方法
为了避免每个实例都拥有独立的方法副本,可以将方法定义在构造函数的原型上。
function Person(name, age) {this.name = name;this.age = age;
}// 将方法添加到 Person.prototype
Person.prototype.greet = function() {console.log("Hello, my name is " + this.name + " and I am " + this.age + " years old.");
};let person3 = new Person("Eve", 35);
person3.greet(); // Hello, my name is Eve and I am 35 years old.
细节:
-
Person.prototype
是一个对象,所有由Person
构造函数创建的实例都会通过原型链继承Person.prototype
上的属性和方法。 -
greet
方法现在只存在一份,被所有Person
实例共享,节约内存。
ES6 class
语法 - 现代JS推荐的面向对象方式
class
是JavaScript中用来创建对象的语法糖,底层依然是原型和构造函数。
class Person {constructor(name, age) {this.name = name;this.age = age;}greet() { // 方法直接定义在类内部,会被添加到原型上console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);}// 静态方法(属于类本身,不属于实例)static sayHello() {console.log("Hello from the Person class!");}
}let person4 = new Person("Frank", 50);
person4.greet(); // Hello, my name is Frank and I am 50 years old.
Person.sayHello(); // Hello from the Person class!
细节:
-
constructor
方法是类默认的构造函数,当使用new
关键字创建实例时,会自动调用它。 -
在
constructor
之外定义的方法会自动添加到原型上。 -
static
关键字用于定义静态方法,只能通过类本身调用,不能通过实例调用。
b. 访问和修改对象属性/方法
点表示法(Dot Notation)
console.log(person.name); // Alice
person.age = 31;
person.greet();
方括号表示法(Bracket Notation)
当属性名包含特殊字符、空格、或是一个变量时,必须使用方括号表示法。
console.log(person["name"]); // Alicelet propName = "age";
console.log(person[propName]); // 31person["favorite-color"] = "blue"; // 可以添加带连字符的属性
console.log(person["favorite-color"]);
c. 删除对象属性
使用delete
运算符。
delete person.isStudent;
console.log(person.isStudent); // undefined
d. 检查属性是否存在
in
运算符
检查属性是否在对象或其原型链上。
console.log("name" in person); // true
console.log("toString" in person); // true (继承自Object.prototype)
console.log("job" in person); // false
hasOwnProperty()
方法
检查属性是否是对象自身的属性(非继承)。
console.log(person.hasOwnProperty("name")); // true
console.log(person.hasOwnProperty("toString")); // false
e. 遍历对象属性
for...in
循环
遍历对象可枚举的属性(包括原型链上的)。
for (let key in person) {console.log(`${key}: ${person[key]}`);
}
// 注意:for...in 会遍历原型链上的可枚举属性,需要结合 hasOwnProperty() 筛选
for (let key in person) {if (person.hasOwnProperty(key)) {console.log(`Own property - ${key}: ${person[key]}`);}
}
Object.keys()
返回一个包含对象自身所有可枚举属性名的数组。
let keys = Object.keys(person);
console.log(keys); // ['name', 'age', 'greet', 'favorite-color']keys.forEach(key => {console.log(`${key}: ${person[key]}`);
});
Object.values()
返回一个包含对象自身所有可枚举属性值的数组。
let values = Object.values(person);
console.log(values); // ['Alice', 31, Function, 'blue']
Object.entries()
返回一个包含对象自身所有可枚举属性的[key, value]
对数组。
let entries = Object.entries(person);
console.log(entries); // [['name', 'Alice'], ['age', 31], ['greet', Function], ['favorite-color', 'blue']]for (let [key, value] of entries) {console.log(`${key}: ${value}`);
}
f. 短属性名和短方法名(ES6)
当变量名和属性名相同时,可以简写。
let myName = "Grace";
let myAge = 22;let user = {myName, // 等同于 myName: myNamemyAge, // 等同于 myAge: myAgewalk() { // 等同于 walk: function() { ... }console.log("Walking...");}
};
console.log(user.myName); // Grace
user.walk(); // Walking...
g. 计算属性名(Computed Property Names)(ES6)
属性名可以是一个表达式的结果。
let prop = "dynamicKey";
let obj = {[prop + "1"]: "value1",['another' + 'Key']: "value2"
};
console.log(obj.dynamicKey1); // value1
console.log(obj.anotherKey); // value2
9.JSON
(1)什么是JSON
-
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于读写和解析。
-
它是基于JavaScript对象字面量语法的文本格式,但不仅限于JavaScript,可以在多种编程语言中使用。
(2)JSON的语法规则
a.基本结构
-
数据是键值对的集合
-
可以是对象(用
{}
包围)或数组(用[]
包围)
b.JSON对象(Object)
{"key1": value1,"key2": value2,...
}
c. JSON数组(Array)
[value1,value2,...
]
d. 数值(Number)
-
支持整数和浮点数
e. 字符串(String)
-
必须用双引号(
"
)包围 -
支持转义字符(如
\n
、\t
、\"
、\\
)
f. 布尔值(Boolean)
g. null值
h. 不能出现
-
单引号(字符串必须双引号)
-
函数、日期对象、undefined(这些在JSON中不被支持)
-
不能有函数作为值
{"name": "John","age": 25,"isStudent": false,"scores": [95, 82, 88],"address": {"city": "New York","zip": "10001"},"skills": null
}
(3)在JavaScript中操作JSON
a.转换为JSON字符串:JSON.stringify
将JavaScript对象转成JSON字符串(常用于数据传输或存储)
const obj = { name: "Alice", age: 30 };
const jsonStr = JSON.stringify(obj);
console.log(jsonStr); // '{"name":"Alice","age":30}'
b. 解析JSON字符串:JSON.parse
将JSON字符串转成JavaScript对象(常用于接收数据)
const jsonStr = '{"name":"Bob","age":25}';
const obj = JSON.parse(jsonStr);
console.log(obj.name); // "Bob"
(4)扩展:自定义对象转JSON的细节
当调用JSON.stringify()
时,可以传入replacer
参数,用于控制序列化过程。
const obj = {name: "Tom",age: 28,greet() { return "Hi"; }
};
console.log(JSON.stringify(obj)); // 无`greet`方法,输出:{"name":"Tom","age":28}// 只序列化特定字段
JSON.stringify(obj, ['name', 'age']);// 美化输出,添加空格缩进
JSON.stringify(obj, null, 2);
-
注意:除数据外,函数和符号会被忽略。
10.BOM
(1)什么是BOM?
BOM(Browser Object Model)是JavaScript在浏览器环境中提供的一组API,用于访问和操作浏览器窗口和与浏览器相关的对象。它提供了除DOM以外的各种工具,使得脚本可以控制浏览器窗口、导航、历史记录、屏幕信息等。
注意:BOM不是标准的一部分,它在不同浏览器中的实现和支持略有差异。
(2)BOM的核心对象和功能
对象 | 描述 | 常用方法或属性 |
---|---|---|
| 浏览器窗口的全局对象,所有BOM对象都通过 | 代理全局变量(如 |
| 当前窗口的URL信息与导航 |
|
| 访问浏览器的历史记录 |
|
| 浏览器信息,比如浏览器类型、版本、操作系统 |
|
| 屏幕相关信息(如宽高、色深) |
|
| 弹窗相关的函数,但这些是全局函数/方法,不是对象 | 弹窗 functions |
| 定时器函数,用于延时或定时操作 |
|
(3)BOM的常用对象及使用细节
a. window
对象
-
定义:整个浏览器窗口的代表,实际上是全局作用域的对象。
-
访问方式:无需
window.
,直接使用(window
是全局对象的引用)。
// 弹出提示框
alert("这是一个提醒");console.log(window.innerWidth); // 视口宽度
console.log(window.location.href); // 当前页面URL
b. location
对象
-
作用:用于获取或设置页面的URL信息和进行导航。
-
常用属性和方法:
属性 / 方法 | 说明 | 示例 |
---|---|---|
| 当前文档的完整URL |
|
| 协议部分( |
|
| 主机名和端口(如 |
|
| 路径部分 |
|
| 查询字符串(URL中 |
|
| URL中的锚点( |
|
| 重新加载页面 |
|
| 跳转到指定URL |
|
| 跳转,但不会在历史记录中留下原页面 |
|
// 导航到新页面
location.href = 'https://www.google.com';// 重新加载页面
location.reload();
c. history
对象
-
作用:操作浏览器的历史记录。
-
常用方法:
方法 | 作用 | 示例 |
---|---|---|
| 后退一页 |
|
| 前进一页 |
|
| 前进或后退n步(n可以为负) |
|
// 后退一页
history.back();// 前进两页
history.go(2);
d. navigator
对象
-
作用:提供有关用户浏览器和设备的信息。
-
常用属性:
属性 | 描述 | 示例 |
---|---|---|
| 浏览器的用户代理字符串 |
|
| 操作系统平台 |
|
| 浏览器应用名(少用,因兼容性差) |
|
| 当前用户的语言偏好 |
|
e. screen
对象
-
作用:显示屏相关信息。
-
常用属性:
属性 | 描述 | 示例 |
---|---|---|
| 屏幕宽度(像素) |
|
| 屏幕高度(像素) |
|
| 色深(每个像素的色彩位数) |
|
| 像素深度 |
|
f. 定时器函数
-
setTimeout()
:延时执行 -
clearTimeout()
:取消超时 -
setInterval()
:周期执行 -
clearInterval()
:取消周期
// 一次性延时
const timerId = setTimeout(() => {alert("一秒后弹出");
}, 1000);// 取消延时
clearTimeout(timerId);// 周期执行
const intervalId = setInterval(() => {console.log("每两秒执行一次");
}, 2000);// 取消周期
clearInterval(intervalId);
(4)弹窗相关函数
-
alert(message)
:显示信息对话框 -
confirm(message)
:显示确认对话框,返回布尔值 -
prompt(message, default)
:输入框,返回用户输入(字符串),或null
。
alert("这是一个提示");if (confirm("是否确定继续?")) {console.log("用户点击确定");
} else {console.log("用户点击取消");
}const name = prompt("请输入你的名字:", "张三");
console.log("用户输入的名字是:" + name);
(5)浏览器宽高与窗口操作
a. innerWidth
和 innerHeight
-
视口(内容区)宽高
-
例:
window.innerWidth
b. outerWidth
和 outerHeight
-
包含边框、滚动条等内容的全窗口尺寸
c. resize
事件
监听窗口变化,动态调整布局。
window.addEventListener('resize', () => {console.log(`窗口宽度:${window.innerWidth}`);
});
d. 弹出新窗口(或标签页)
// 打开新窗口
const newWin = window.open("https://example.com", "_blank");// 关闭窗口
newWin.close();
e. 控制窗口大小与位置
-
resizeTo(width, height)
:调整当前窗口大小 -
moveTo(x, y)
:移动窗口(注意大部分浏览器限制)
window.resizeTo(800, 600);
window.moveTo(100, 100);
11.DOM
(1)什么是DOM
-
DOM(Document Object Model,文档对象模型)是HTML和XML文档的编程接口。
-
它以树状结构(节点树)表示页面的所有内容,每个元素、属性、文本都是节点。
-
JavaScript可以通过DOM操作网页,实现动态内容更新和交互。
(2)DOM的基本结构
-
树状结构:
-
Document:整个文档的入口对象。
-
元素节点(Element):网页的标签(
<div>
,<p>
,<a>
等)。 -
文本节点(Text):元素内部的文本内容。
-
属性节点(Attr):标签的属性。
-
注释节点(Comment):HTML中的注释。
-
Document├── html├── head└── body├── div│ └── text└── p└── text
(3)常用的DOM操作语法和细节
a. 访问元素
方法 | 作用 | 例子 |
---|---|---|
| 按ID获取元素 |
|
| 按标签名获取元素(HTMLCollection,类数组) |
|
| 按类名获取元素(HTMLCollection) |
|
| 选择第一个符合条件的元素(CSS选择器) |
|
| 选择所有符合条件的元素,返回NodeList |
|
b. 修改元素
-
修改内容:
element.innerHTML = '新的HTML内容'; // 更改元素内部HTML
element.textContent = '纯文本内容'; // 仅文本内容
-
修改样式:
element.style.color = 'red';
element.style.backgroundColor = 'blue';
-
修改属性:
element.setAttribute('title', '提示信息'); // 添加或修改属性
const title = element.getAttribute('title'); // 获取属性
// 也可以直接用属性访问
element.id = 'newId'; // 直接通过属性
c. 创建新元素
const newDiv = document.createElement('div'); // 创建一个div元素
newDiv.innerHTML = '我是新添加的元素'; // 赋内容
document.body.appendChild(newDiv); // 添加到body尾部
d. 删除元素
const parent = document.getElementById('parentId');
const child = document.getElementById('childId');
parent.removeChild(child); // 从父元素中删除子元素
// 也可以直接使用
child.remove(); // 现代浏览器支持
e. 事件绑定
-
添加事件监听器:
element.addEventListener('click', function(event) {alert('元素被点击了!');
});
-
移除事件监听器(需要用到引用函数):
function handleClick() {alert('点击事件');
}
element.addEventListener('click', handleClick);
// 移除
element.removeEventListener('click', handleClick);
f. 其他常用操作
-
获取子元素:
element.children; // 元素的子元素(HTMLCollection)
element.childNodes; // 所有子节点(包括文本、注释)
-
兄弟元素:
element.nextElementSibling; // 下一个兄弟元素
element.previousElementSibling; // 上一个兄弟元素
-
父元素:
element.parentNode; // 或 parentElement
(4)DOM操作的细节注意点
-
性能:
-
多次操作DOM可能影响性能,建议批量操作或使用文档片段(
DocumentFragment
)
-
-
兼容性:
-
getElementsByClassName
和querySelector
在现代浏览器都支持
-
-
动态更新UI:
-
修改
innerHTML
和textContent
会影响子元素,要小心使用
-
-
事件代理:
-
给父元素绑定事件,利用冒泡机制管理子元素事件,提高效率
-
-
classList
API:
element.classList.add('newClass');
element.classList.remove('oldClass');
element.classList.toggle('active');
element.classList.contains('active');
(5)示例
<!DOCTYPE html>
<html lang="zh-CN">
<head><!-- 字符集为UTF-8 --><meta charset="UTF-8"><!-- 设置浏览器兼容性 --><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>DOM操作示例</title>
</head>
<body><div id="container"><p class="text">这是一个段落</p><button id="btn">点击我</button></div><script>const btn = document.getElementById('btn');btn.addEventListener('click', () => {// 创建新元素const newParagraph = document.createElement('p');newParagraph.textContent = '新添加的段落';// 添加样式newParagraph.style.color = 'blue';// 添加到容器中document.getElementById('container').appendChild(newParagraph);// 修改已有元素const existingPara = document.querySelector('.text');existingPara.textContent = '内容被修改了';// 移除按钮(示例)btn.remove();});</script>
</body>
</html>