第十章JavaScript的应用

10.1 JavaScript概述

JavaScript 是一种广泛使用的轻量级编程语言,主要用于实现网页上的动态效果。它由 Netscape 公司在 1995 年开发,并成为了 Web 开发不可或缺的一部分。

10.1.1 JavaScript简介

1 简单性

JavaScript 设计之初就考虑到了非专业程序员的使用,因此它的语法相对简单,容易上手。

2 动态性

JavaScript 是一种解释型语言,代码可以在运行时被解释执行,这使得 JavaScript 具有高度的灵活性和动态性。

3 跨平台性

JavaScript 可以在多种操作系统和浏览器上运行,无需编译即可跨平台使用。

4 安全性

为了保护用户的安全,JavaScript 在浏览器中运行时受到沙箱环境的限制,不能直接访问用户的硬盘数据或执行其他可能危害系统的操作。

5 基于对象的语言

虽然 JavaScript 不是完全面向对象的编程语言,但它支持基于对象的编程方式,可以通过对象来组织代码,实现复杂的功能。

10.1.2 JavaScript入门案例

  1. 用 JavaScript 输出文本

这是最基础的 JavaScript 案例,通过 alert、console.log 和 document.write 等方法在网页上显示文本。

示例代码:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript 输出文本</title>
</head>
<body>
    <script>
        // 使用 alert 显示警告框
        alert('Hello, World!');
 
        // 使用 console.log 在控制台输出
        console.log('Hello, Console!');
 
        // 使用 document.write 在页面中输出
        document.write('Hello, Document!');
    </script>
</body>
</html>

说明:

alert('Hello, World!'); 会在浏览器中弹出一个警告框,显示 "Hello, World!"。

console.log('Hello, Console!'); 会在浏览器的开发者工具控制台中输出 "Hello, Console!"。

document.write('Hello, Document!'); 会将 "Hello, Document!" 直接写入到 HTML 文档中。

  1. 用 JavaScript 改变 HTML 元素

通过 JavaScript 可以动态地改变 HTML 元素的内容、属性或样式。

示例代码:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript 改变 HTML 元素</title>
</head>
<body>
    <p id="demo">这是一个段落。</p>
    <button onclick="changeText()">点击改变文本</button>
 
    <script>
        function changeText() {
            document.getElementById('demo').innerHTML = '文本已被改变。';
        }
    </script>
</body>
</html>

说明:

document.getElementById('demo') 通过 ID 选择器获取指定的 HTML 元素。

innerHTML 属性用于设置或获取元素的 HTML 内容。

οnclick="changeText()" 为按钮添加点击事件处理器,当按钮被点击时调用 changeText 函数。

  1. 一个外部 JavaScript 文件

将 JavaScript 代码放在外部文件中,可以提高代码的可维护性和重用性。

HTML 文件:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>外部 JavaScript 文件</title>
</head>
<body>
    <p id="external-demo">这是一个段落。</p>
    <button onclick="externalChangeText()">点击改变文本</button>
 
    <script src="external-script.js"></script>
</body>
</html>

外部 JavaScript 文件 (external-script.js)

html 复制代码
function externalChangeText() {
    document.getElementById('external-demo').innerHTML = '文本已被外部脚本改变。';
}

说明:

src="external-script.js" 通过 src 属性引入外部 JavaScript 文件。

外部 JavaScript 文件中的函数可以在 HTML 文件中调用。

  1. 响应用户事件

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>
    <input type="text" id="input-text" placeholder="请输入文本">
    <p id="event-demo"></p>
 
    <script>
        document.getElementById('input-text').addEventListener('keyup', function(event) {
            document.getElementById('event-demo').innerText = '你输入了: ' + event.target.value;
        });
    </script>
</body>
</html>

说明:

addEventListener 方法用于为元素添加事件监听器。

keyup 事件在用户释放键盘上的键时触发。

event.target.value 获取输入框中的当前值。

  1. 使用条件语句

JavaScript 中的条件语句(如 if...else)用于根据不同的条件执行不同的代码块。

示例代码:

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>
    <input type="number" id="age-input" placeholder="请输入年龄">
    <button onclick="checkAge()">检查年龄</button>
    <p id="age-result"></p>
 
    <script>
        function checkAge() {
            var age = document.getElementById('age-input').value;
            if (age >= 18) {
                document.getElementById('age-result').innerText = '你已成年。';
            } else {
                document.getElementById('age-result').innerText = '你还未成年。';
            }
        }
    </script>
</body>
</html>

说明:

if (age >= 18) 检查输入的年龄是否大于或等于 18。

else 分支用于处理不符合条件的情况。

10.1.3 JavaScript放置的位置

1 head标记中的脚本

将 <script> 标签放在 <head> 标签内是一种常见的做法,特别是在需要在页面加载前执行某些初始化代码时。

示例代码:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript in Head</title>
    <script>
        function initialize() {
            console.log('Page initialization');
        }
        window.onload = initialize;
    </script>
</head>
<body>
    <h1>Welcome to My Website</h1>
</body>
</html>

优点:

确保在页面完全加载之前不会阻塞或运行 JavaScript 代码。

适合放置全局变量和函数定义,尤其是那些需要在页面加载时立即执行的代码。

缺点:

如果脚本较大,可能会延迟页面的渲染,导致用户看到空白页面。

不利于页面内容的快速呈现。

2 body标记中的脚本

将 <script> 标签放在 <body> 标签内,特别是放在页面内容的底部,是一种推荐的做法,可以确保页面内容在 JavaScript 代码执行前已经加载完毕。

示例代码:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript in Body</title>
</head>
<body>
    <h1>Welcome to My Website</h1>
    <p>This is some content.</p>
    <script>
        function initialize() {
            console.log('Page initialization');
        }
        initialize();
    </script>
</body>
</html>

优点:

确保页面内容在 JavaScript 代码执行前已经加载完毕,提高用户体验。

适合放置需要操作 DOM 的代码,因为此时 DOM 已经构建完成。

缺点:

如果脚本需要在页面加载前执行,可能会导致延迟。

3 外部js文件中的脚本

将 JavaScript 代码放在外部文件中,然后通过 <script> 标签的 src 属性引入,是一种常见的做法,有助于代码的重用和维护。

示例代码:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>External JavaScript File</title>
</head>
<body>
    <h1>Welcome to My Website</h1>
    <p>This is some content.</p>
    <script src="script.js"></script>
</body>
</html>

外部 JavaScript 文件 (script.js)

html 复制代码
function initialize() {
    console.log('Page initialization');
}
 
initialize();

优点:

代码重用性高,多个页面可以共享同一个 JavaScript 文件。

有利于代码的组织和维护,使 HTML 文件更加简洁。

浏览器可以缓存外部 JavaScript 文件,提高页面加载速度。

缺点:

需要额外的 HTTP 请求来获取外部文件,可能会增加页面的加载时间。

4 事件处理代码中的脚本

将 JavaScript 代码直接嵌入到 HTML 标签的事件属性中,如 onclick、onload 等,是一种内联的方式,适合简单的事件处理。

示例代码:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Inline Event Handlers</title>
</head>
<body>
    <h1>Welcome to My Website</h1>
    <button onclick="alert('Button clicked!')">Click Me</button>
</body>
</html>

优点:

简单直观,适用于简单的事件处理。

代码和事件处理逻辑紧密结合,便于理解。

缺点:

违反了内容与行为分离的原则,不利于代码的维护和复用。

如果页面中有大量内联 JavaScript,会导致 HTML 代码变得混乱且难以管理。

10.2 JavaScript语法

10.2.1 语法基础

1 区分大小写

JavaScript 是一种区分大小写的语言,这意味着变量名 myVariable 和 myvariable 被视为两个不同的变量。

2 变量不区分类型

JavaScript 是一种弱类型语言,变量在声明时不需要指定类型,类型会根据赋给变量的值自动确定。

3 每行代码结尾可以省略分号

虽然分号用于表示语句的结束,但在大多数情况下,JavaScript 解析器能够自动插入分号。

4 注释与C、C++、Java等语言相同

单行注释使用 //,多行注释使用 /* */

10.2.2 标识符和常用变量

1 标识符

用于命名变量、函数等的名称,必须以字母、下划线 _ 或美元符号 $ 开始,后续字符可以是字母、数字、下划线或美元符号。

2 变量声明

在 JavaScript 中,变量用于存储数据值。变量可以通过 var、let 或 const 关键字来声明。var 是最早的变量声明方式,但 let 和 const 是 ES6 引入的新关键字,提供了更好的块级作用域和常量支持。

示例代码:

html 复制代码
var x = 10; // 使用 var 声明变量
let y = 20; // 使用 let 声明变量
const z = 30; // 使用 const 声明常量

注意事项:

var 声明的变量具有函数级作用域,即使在块 {} 内声明,也会提升到函数顶部。

let 和 const 声明的变量具有块级作用域,仅在声明它们的块 {} 内有效。

const 声明的变量必须初始化,并且不能重新赋值,但如果是对象或数组,其属性或元素可以修改。

3 变量类型

JavaScript 有多种数据类型,包括原始数据类型和引用数据类型。

原始数据类型:

number:数字,包括整数和浮点数。

string:字符串,可以使用单引号或双引号表示。

boolean:布尔值,只有 true 和 false 两个值。

null:表示空值或不存在的对象。

undefined:表示未定义的值。

symbol:ES6 引入的一种新数据类型,用于创建唯一的标识符。

引用数据类型:

object:对象,可以包含多个属性和方法。

array:数组,用于存储多个值。

function:函数,可以作为值传递和返回。

示例代码:

html 复制代码
let num = 10; // number
let str = "Hello, World!"; // string
let bool = true; // boolean
let n = null; // null
let u = undefined; // undefined
let sym = Symbol("key"); // symbol
let obj = { name: "Alice", age: 25 }; // object
let arr = [1, 2, 3]; // array
let func = function() { console.log("Hello"); }; // function

注意事项:

typeof 运算符可以用于获取变量的数据类型。

null 和 undefined 的 typeof 结果分别为 "object" 和 "undefined",这是 JavaScript 的一个历史遗留问题。

10.2.3 运算符与表达式

1 算术运算符和表达式

+:加法

-:减法

*:乘法

/:除法

%:取模

**:幂运算

示例代码:

html 复制代码
let a = 10;
let b = 5;
console.log(a + b); // 15
console.log(a - b); // 5
console.log(a * b); // 50
console.log(a / b); // 2
console.log(a % b); // 0
console.log(a ** b); // 100000
2 关系运算符和表达式
  • ==:等于
  • ===:严格等于(值和类型都相等)
  • !=:不等于
  • !==:严格不等于
  • >:大于
  • <:小于
  • >=:大于等于
  • <=:小于等于

示例代码

html 复制代码
let x = 10;
let y = "10";
console.log(x == y); // true
console.log(x === y); // false
console.log(x != y); // false
console.log(x !== y); // true
console.log(x > y); // false
console.log(x < y); // false
console.log(x >= y); // true
console.log(x <= y); // true
3 逻辑运算符和表达式
  • &&:逻辑与
  • ||:逻辑或
  • !:逻辑非

示例代码

html 复制代码
let p = true;
let q = false;
console.log(p && q); // false
console.log(p || q); // true
console.log(!p); // false
4 赋值运算符和表达式
  • =:简单赋值
  • +=:加法赋值
  • -=:减法赋值
  • *=:乘法赋值
  • /=:除法赋值
  • %=:取模赋值
  • **=:幂赋值

示例代码

html 复制代码
let a = 10;
a += 5; // a = a + 5
console.log(a); // 15
a -= 3; // a = a - 3
console.log(a); // 12
a *= 2; // a = a * 2
console.log(a); // 24
a /= 4; // a = a / 4
console.log(a); // 6
a %= 2; // a = a % 2
console.log(a); // 0
a **= 2; // a = a ** 2
console.log(a); // 0
5 条件运算符和表达式
条件运算符(三目运算符)用于在一行代码中完成条件判断和赋值操作。语法如下:
condition ? expr1 : expr2
示例代码
html 复制代码
let age = 20;
let message = (age >= 18) ? "成年人" : "未成年人";
console.log(message); // 成年人

注意事项

  • 条件运算符的优先级较高,使用时需要注意括号的使用。
6 逗号运算符和表达式

表达式是由一个或多个变量、常量、运算符和括号组成的序列。它可以是一个简单的值,也可以是一个复杂的计算过程。表达式求值按运算符的优先级和结合性规定的顺序进行。

示例代码

html 复制代码
let a = 10;
let b = 5;
let c = 3;
 
let result = (a + b) * c;
console.log(result); // 45

注意事项

  • 括号可以改变运算符的优先级。
  • 表达式可以嵌套使用,形成更复杂的逻辑。
7. 位运算符

位运算符用于对二进制数进行位操作。JavaScript 支持的位运算符如下:

  • &:按位与
  • |:按位或
  • ^:按位异或
  • ~:按位非
  • <<:左移
  • >>:右移
  • >>>:无符号右移

示例代码

html 复制代码
let a = 5; // 二进制 0101
let b = 3; // 二进制 0011
 
console.log(a & b); // 1 (二进制 0001)
console.log(a | b); // 7 (二进制 0111)
console.log(a ^ b); // 6 (二进制 0110)
console.log(~a); // -6 (二进制 1010)
console.log(a << 1); // 10 (二进制 1010)
console.log(a >> 1); // 2 (二进制 0010)
console.log(a >>> 1); // 2 (二进制 0010)

注意事项

  • 位运算符通常用于低级别的数据操作,如图像处理、网络通信等。

10.2.4 程序设计

1 条件分支语句

条件语句

  • if 语句
  • if-else 语句
  • if-else if-else 语句
  • switch 语句

示例代码

html 复制代码
let age = 20;
 
if (age < 18) {
    console.log("未成年");
} else if (age >= 18 && age < 60) {
    console.log("成年");
} else {
    console.log("老年");
}
 
let grade = "A";
 
switch (grade) {
    case "A":
        console.log("优秀");
        break;
    case "B":
        console.log("良好");
        break;
    case "C":
        console.log("及格");
        break;
    default:
        console.log("不及格");
}
2 循环语句
  • for 循环
  • while 循环
  • do-while 循环
  • for-in 循环
  • for-of 循环

示例代码

html 复制代码
// for 循环
for (let i = 0; i < 5; i++) {
    console.log(i);
}
 
// while 循环
let j = 0;
while (j < 5) {
    console.log(j);
    j++;
}
 
// do-while 循环
let k = 0;
do {
    console.log(k);
    k++;
} while (k < 5);
 
// for-in 循环
let obj = { a: 1, b: 2, c: 3 };
for (let key in obj) {
    console.log(key, obj[key]);
}
 
// for-of 循环
let arr = [1, 2, 3, 4, 5];
for (let value of arr) {
    console.log(value);
}
10.2.5 函数
1 定义函数
在JavaScript中,定义一个函数的基本语法如下:
html 复制代码
function functionName(parameters) {
  // 函数体
  // 执行的代码
  [return returnValue;]
}

function 关键字用于声明一个函数。

functionName 是函数的名字,必须在同一个页面中是唯一的,并且区分大小写。

parameters 是可选的参数列表,多个参数之间用逗号分隔。

函数体是包含在大括号 {} 中的代码块,用于实现函数的功能。

return 关键字是可选的,用于返回函数的值。如果没有 return 语句,函数默认返回 undefined。

示例:定义一个简单的函数,用于在页面上输出"你好"。

html 复制代码
function sayHello() {
  document.write('你好');
}
2 函数调用
定义了函数之后,需要通过调用函数来执行其中的代码。调用函数的基本语法如下:
html 复制代码
functionName(arguments);
  • functionName 是要调用的函数的名字。
  • arguments 是传递给函数的实际参数,多个参数之间用逗号分隔。

示例 :调用上面定义的 sayHello 函数。

sayHello();
3. 函数参数

函数参数分为形式参数(形参)和实际参数(实参):

  • 形参:在定义函数时指定的参数,用于接收调用函数时传递的实际值。
  • 实参:在调用函数时传递的实际值。

示例:定义一个带有参数的函数,用于计算两个数的和。

html 复制代码
function addNumbers(num1, num2) {
  return num1 + num2;
}
 
let result = addNumbers(5, 3);
console.log(result); // 输出 8
4 函数返回值

函数可以通过 return 语句返回一个值。返回值可以是任意类型的值,包括数字、字符串、对象、数组等。

示例:定义一个返回最大值的函数。

html 复制代码
function max(a, b) {
  if (a > b) {
    return a;
  } else {
    return b;
  }
}
 
let maxValue = max(10, 20);
console.log(maxValue); // 输出 20
  1. 函数的作用域

在JavaScript中,变量的作用域决定了变量的可见性和生命周期。主要有两种作用域:

全局作用域:在函数外部声明的变量具有全局作用域,可以在整个页面中访问。

局部作用域:在函数内部声明的变量具有局部作用域,只能在函数内部访问。

示例:展示全局变量和局部变量的区别。

html 复制代码
let globalVar = '我是全局变量';
 
function myFunction() {
  let localVar = '我是局部变量';
  console.log(globalVar); // 输出 '我是全局变量'
  console.log(localVar);  // 输出 '我是局部变量'
}
 
myFunction();
console.log(globalVar); // 输出 '我是全局变量'
console.log(localVar);  // 报错:localVar is not defined

10.3 JavaScript对象

10.3.1 对象基础

1 概述

在 JavaScript 中,对象是一种复杂的数据类型,它可以包含多个属性和方法。属性是与对象关联的值,而方法是在对象上执行的动作。对象可以用来表示现实世界中的实体,例如一个人、一辆车等。

示例:创建一个表示人的对象。

html 复制代码
let person = {
  name: 'Alice',
  age: 30,
  greet: function() {
    console.log(`你好,${this.name}!`);
  }
};

在这个例子中,person 对象有两个属性 name 和 age,以及一个方法 greet。

  1. 创建对象的方式

JavaScript 提供了多种创建对象的方式,包括对象字面量、构造函数、Object.create 方法等。

2.1 对象字面量

对象字面量是最简单和常用的创建对象的方式,通过一对大括号 {} 包含键值对来定义对象。

示例:

html 复制代码
let person = {
  name: 'Alice',
  age: 30,
  greet: function() {
    console.log(`你好,${this.name}!`);
  }
};
2.2 构造函数

构造函数是一种特殊的函数,用于创建和初始化对象。构造函数的名称通常首字母大写,以区别于普通函数。

示例

html 复制代码
function Person(name, age) {
  this.name = name;
  this.age = age;
  this.greet = function() {
    console.log(`你好,${this.name}!`);
  };
}
 
let alice = new Person('Alice', 30);
alice.greet(); // 输出 '你好,Alice!'
2.3 Object.create 方法

Object.create 方法用于创建一个新对象,并指定其原型对象。

示例

html 复制代码
let personPrototype = {
  greet: function() {
    console.log(`你好,${this.name}!`);
  }
};
 
let alice = Object.create(personPrototype);
alice.name = 'Alice';
alice.age = 30;
 
alice.greet(); // 输出 '你好,Alice!'
3. 访问和修改对象的属性
3.1 访问属性

可以通过点操作符 . 或方括号 [] 来访问对象的属性。

示例

html 复制代码
let person = {
  name: 'Alice',
  age: 30
};
 
console.log(person.name); // 输出 'Alice'
console.log(person['age']); // 输出 30
3.2 修改属性

同样可以通过点操作符 . 或方括号 [] 来修改对象的属性。

示例

html 复制代码
let person = {
  name: 'Alice',
  age: 30
};
 
person.name = 'Bob';
person['age'] = 31;
 
console.log(person.name); // 输出 'Bob'
console.log(person.age); // 输出 31
3.3 添加属性

可以在对象中动态地添加新的属性。

示例

html 复制代码
let person = {
  name: 'Alice'
};
 
person.age = 30;
person['job'] = 'Engineer';
 
console.log(person); // 输出 { name: 'Alice', age: 30, job: 'Engineer' }
3.4 删除属性

可以使用 delete 关键字来删除对象的属性。

示例

html 复制代码
let person = {
  name: 'Alice',
  age: 30
};
 
delete person.age;
console.log(person); // 输出 { name: 'Alice' }
4. 对象的方法

方法是对象中的函数。可以通过点操作符 . 或方括号 [] 来调用对象的方法。

示例

html 复制代码
let person = {
  name: 'Alice',
  age: 30,
  greet: function() {
    console.log(`你好,${this.name}!`);
  }
};
 
person.greet(); // 输出 '你好,Alice!'
person['greet'](); // 输出 '你好,Alice!'

10.3.2 常用对象

1 window对象

代表浏览器窗口,是所有 JavaScript 全局对象、函数和变量的父对象。

2 document对象

提供对文档的操作接口,可以用来获取和修改页面内容。

3 location对象

包含有关当前 URL 的信息,以及用于导航的方法。

4 navigator对象

提供了关于浏览器的信息。

5 screen对象

提供了有关用户屏幕的信息。

6 其他对象

Array 对象

Array 对象用于创建和操作数组。数组是存储多个值的有序集合。

常用方法:

push(element, ..., elementN):向数组末尾添加一个或多个元素,并返回新的长度。

pop():删除数组的最后一个元素,并返回该元素。

shift():删除数组的第一个元素,并返回该元素。

unshift(element, ..., elementN):向数组开头添加一个或多个元素,并返回新的长度。

splice(start, deleteCount, item1, ..., itemN):从数组中添加或删除元素。

slice(start, end):返回从开始到结束(不包括结束)的数组的一部分浅拷贝。

map(callback, thisArg):创建一个新数组,其结果是该数组每个元素调用一个提供的函数。

filter(callback, thisArg):创建一个新数组,包含通过测试的元素。

reduce(callback, initialValue):对数组中的每个元素执行一个提供的函数,将其结果汇总为单个值。

forEach(callback, thisArg):对数组中的每个元素执行一次提供的函数。

示例:

html 复制代码
let numbers = [1, 2, 3, 4, 5];
 
numbers.push(6);
console.log(numbers); // 输出 [1, 2, 3, 4, 5, 6]
 
numbers.pop();
console.log(numbers); // 输出 [1, 2, 3, 4, 5]
 
numbers.shift();
console.log(numbers); // 输出 [2, 3, 4, 5]
 
numbers.unshift(1);
console.log(numbers); // 输出 [1, 2, 3, 4, 5]
 
numbers.splice(1, 1, 2.5);
console.log(numbers); // 输出 [1, 2.5, 3, 4, 5]
 
let part = numbers.slice(1, 3);
console.log(part); // 输出 [2.5, 3]
 
let doubled = numbers.map(x => x * 2);
console.log(doubled); // 输出 [2, 5, 6, 8, 10]
 
let even = numbers.filter(x => x % 2 === 0);
console.log(even); // 输出 [2, 4]
 
let sum = numbers.reduce((acc, curr) => acc + curr, 0);
console.log(sum); // 输出 15
 
numbers.forEach(x => console.log(x)); // 输出 1 2.5 3 4 5

String 对象

String 对象用于创建和操作字符串。字符串是不可变的字符序列。

常用方法:

length:返回字符串的长度。

charAt(index):返回指定位置的字符。

charCodeAt(index):返回指定位置字符的 Unicode 编码。

concat(str1, ..., strN):连接两个或多个字符串。

indexOf(searchValue, fromIndex):返回指定值首次出现的位置。

lastIndexOf(searchValue, fromIndex):返回指定值最后一次出现的位置。

includes(searchValue, position):判断字符串是否包含指定的子字符串。

startsWith(searchValue, position):判断字符串是否以指定的子字符串开头。

endsWith(searchValue, length):判断字符串是否以指定的子字符串结尾。

split(separator, limit):将字符串分割为数组。

trim():去除字符串两端的空白字符。

toLowerCase():将字符串转换为小写。

toUpperCase():将字符串转换为大写。

replace(searchValue, replaceValue):替换字符串中的指定子字符串。

match(regexp):在字符串中执行正则表达式匹配。

示例:

html 复制代码
let str = 'Hello, World!';
 
console.log(str.length); // 输出 13
console.log(str.charAt(0)); // 输出 'H'
console.log(str.charCodeAt(0)); // 输出 72
 
let combined = str.concat(' How are you?');
console.log(combined); // 输出 'Hello, World! How are you?'
 
console.log(str.indexOf('World')); // 输出 7
console.log(str.lastIndexOf('l')); // 输出 10
 
console.log(str.includes('World')); // 输出 true
console.log(str.startsWith('Hello')); // 输出 true
console.log(str.endsWith('!')); // 输出 true
 
let words = str.split(', ');
console.log(words); // 输出 ['Hello', ' World!']
 
console.log(str.trim()); // 输出 'Hello, World!'
console.log(str.toLowerCase()); // 输出 'hello, world!'
console.log(str.toUpperCase()); // 输出 'HELLO, WORLD!'
 
let replaced = str.replace('World', 'JavaScript');
console.log(replaced); // 输出 'Hello, JavaScript!'
 
let matched = str.match(/\w+/g);
console.log(matched); // 输出 ['Hello', 'World']

Number 对象

Number 对象用于创建和操作数字。Number 对象提供了许多静态属性和方法,用于处理数字。

常用方法:

toString(radix):将数字转换为字符串,可以指定进制。

toFixed(digits):将数字转换为字符串,保留指定的小数位数。

toPrecision(precision):将数字转换为字符串,保留指定的有效数字。

parseInt(string, radix):解析字符串并返回整数。

parseFloat(string):解析字符串并返回浮点数。

isNaN(value):判断值是否为 NaN。

isFinite(value):判断值是否为有限的。

isInteger(value):判断值是否为整数。

parseFloat(string):解析字符串并返回浮点数。

示例:

html 复制代码
let num = 123.456;
 
console.log(num.toString()); // 输出 '123.456'
console.log(num.toString(16)); // 输出 '7b.7333333333333'
 
console.log(num.toFixed(2)); // 输出 '123.46'
console.log(num.toPrecision(4)); // 输出 '123.5'
 
console.log(Number.parseInt('123', 10)); // 输出 123
console.log(Number.parseFloat('123.456')); // 输出 123.456
 
console.log(Number.isNaN('123')); // 输出 false
console.log(Number.isNaN(NaN)); // 输出 true
 
console.log(Number.isFinite(123)); // 输出 true
console.log(Number.isFinite(Infinity)); // 输出 false
 
console.log(Number.isInteger(123)); // 输出 true
console.log(Number.isInteger(123.456)); // 输出 false
Boolean 对象

Boolean 对象用于创建和操作布尔值。布尔值只有两个可能的值:truefalse

常用方法

  • Boolean(value):将值转换为布尔值。

示例

html 复制代码
console.log(Boolean(1)); // 输出 true
console.log(Boolean(0)); // 输出 false
console.log(Boolean('Hello')); // 输出 true
console.log(Boolean('')); // 输出 false
console.log(Boolean([])); // 输出 true
console.log(Boolean({})); // 输出 true
console.log(Boolean(null)); // 输出 false
console.log(Boolean(undefined)); // 输出 false

Date 对象

Date 对象用于创建和操作日期和时间。Date 对象提供了许多方法,用于获取和设置日期和时间。

常用方法:

new Date():创建一个新的 Date 对象,表示当前日期和时间。

new Date(dateString):创建一个新的 Date 对象,表示指定的日期字符串。

new Date(year, month, day, hours, minutes, seconds, milliseconds):创建一个新的 Date 对象,表示指定的日期和时间。

getFullYear():返回四位数的年份。

getMonth():返回月份(0 表示 1 月,11 表示 12 月)。

getDate():返回月份中的日期(1 到 31)。

getDay():返回星期几(0 表示星期日,1 表示星期一,依此类推)。

getHours():返回小时(0 到 23)。

getMinutes():返回分钟(0 到 59)。

getSeconds():返回秒(0 到 59)。

getMilliseconds():返回毫秒(0 到 999)。

getTime():返回自 1970 年 1 月 1 日 00:00:00 UTC 以来的毫秒数。

toISOString():返回 ISO 8601 格式的日期字符串。

toLocaleDateString():返回本地格式的日期字符串。

toLocaleTimeString():返回本地格式的时间字符串。

setFullYear(year, month, day):设置年份、月份和日期。

setMonth(month, day):设置月份和日期。

setDate(date):设置日期。

setHours(hours, minutes, seconds, milliseconds):设置小时、分钟、秒和毫秒。

setMinutes(minutes, seconds, milliseconds):设置分钟、秒和毫秒。

setSeconds(seconds, milliseconds):设置秒和毫秒。

setMilliseconds(milliseconds):设置毫秒。

setTime(time):设置自 1970 年 1 月 1 日 00:00:00 UTC 以来的毫秒数。

示例:

html 复制代码
let now = new Date();
console.log(now); // 输出当前日期和时间
 
let date = new Date('2023-10-10');
console.log(date); // 输出 2023-10-10T00:00:00.000Z
 
let customDate = new Date(2023, 9, 10, 12, 30, 0, 0);
console.log(customDate); // 输出 2023-10-10T12:30:00.000Z
 
console.log(now.getFullYear()); // 输出 2023
console.log(now.getMonth()); // 输出 9
console.log(now.getDate()); // 输出 10
console.log(now.getDay()); // 输出 2
console.log(now.getHours()); // 输出 12
console.log(now.getMinutes()); // 输出 30
console.log(now.getSeconds()); // 输出 0
console.log(now.getMilliseconds()); // 输出 0
console.log(now.getTime()); // 输出 1696938600000
console.log(now.toISOString()); // 输出 2023-10-10T12:30:00.000Z
console.log(now.toLocaleDateString()); // 输出 10/10/2023
console.log(now.toLocaleTimeString()); // 输出 12:30:00 PM
 
now.setFullYear(2024);
console.log(now.getFullYear()); // 输出 2024
 
now.setMonth(10);
console.log(now.getMonth()); // 输出 10
 
now.setDate(15);
console.log(now.getDate()); // 输出 15
 
now.setHours(18, 30, 0, 0);
console.log(now.getHours()); // 输出 18
console.log(now.getMinutes()); // 输出 30
console.log(now.getSeconds()); // 输出 0
console.log(now.getMilliseconds()); // 输出 0
 
now.setMilliseconds(500);
console.log(now.getMilliseconds()); // 输出 500
 
now.setTime(1702176600000);
console.log(now); // 输出 2023-12-10T12:30:00.000Z

10.4 JavaScript事件

  1. 事件的基本概念

事件是指在特定条件下执行的代码块,通常是由用户的交互行为触发的。在 JavaScript 中,事件可以是用户的鼠标点击、键盘按键、页面加载、表单提交等。当事件被触发时,JavaScript 会自动执行与该事件相关的代码块,从而实现特定的功能。

事件处理程序(Event Handler)是一段 JavaScript 代码,总是与页面中的特定部分以及一定的事件相关联。当与页面特定部分相关联的事件发生时,事件处理程序就会被调用。

  1. 事件处理方式

JavaScript 提供了多种方式来处理事件,主要包括以下三种:

HTML 事件处理程序:直接在 HTML 元素中添加事件处理程序。

<button οnclick="alert('Hello, World!')">Click Me</button>

2.DOM0 级事件处理程序:通过 JavaScript 为元素添加事件处理程序。

html 复制代码
<button id="myButton">Click Me</button>
<script>
  document.getElementById('myButton').addEventListener('click', function() {
    alert('Hello, World!');
  });
</script>

DOM2 级事件处理程序 :使用 addEventListenerremoveEventListener 方法来添加和移除事件处理程序。

html 复制代码
<button id="myButton">Click Me</button>
<script>
  document.getElementById('myButton').addEventListener('click', function() {
    alert('Hello, World!');
  });
</script>

注意:HTML 事件处理程序虽然简单易用,但由于其耦合性较高,不推荐在大型项目中使用。DOM0 级事件处理程序和 DOM2 级事件处理程序是更推荐的方式,尤其是 DOM2 级事件处理程序,因为它支持同一个事件绑定多个处理程序。

  1. 事件对象

当事件被触发时,会生成一个事件对象(Event Object),该对象包含了与事件相关的信息。事件对象作为参数传递给事件处理程序函数。通过事件对象,可以获取事件的详细信息,如事件类型、事件目标、事件的坐标等。

常用属性:

type:事件的类型,如 'click'、'mouseover' 等。

target:事件的目标元素,即触发事件的元素。

currentTarget:当前绑定事件处理程序的元素。

bubbles:事件是否冒泡。

cancelable:事件是否可以取消。

defaultPrevented:是否调用了 preventDefault 方法。

eventPhase:事件当前处于哪个阶段(捕获、目标、冒泡)。

timeStamp:事件生成的时间戳。

clientX 和 clientY:鼠标相对于视口的坐标。

pageX 和 pageY:鼠标相对于页面的坐标。

常用方法:

stopPropagation():阻止事件继续在 DOM 树中传播。

stopImmediatePropagation():阻止事件继续在 DOM 树中传播,并阻止其他事件处理程序被调用。

preventDefault():阻止事件的默认行为。

示例:

html 复制代码
<button id="myButton">Click Me</button>
<script>
  document.getElementById('myButton').addEventListener('click', function(event) {
    console.log('Event Type:', event.type);
    console.log('Event Target:', event.target);
    console.log('Current Target:', event.currentTarget);
    console.log('Client X:', event.clientX);
    console.log('Client Y:', event.clientY);
    console.log('Page X:', event.pageX);
    console.log('Page Y:', event.pageY);
 
    event.preventDefault(); // 阻止默认行为
    event.stopPropagation(); // 阻止事件传播
  });
</script>
  1. 事件流

事件流描述了页面中接受事件的顺序。在浏览器发展的初期,两大浏览器厂商 IE 和 Netscape 对事件流的解释出现了两种截然相反的定义:

事件捕获(Event Capturing):事件最早由不太具体的节点接收,而最具体的节点最后接收到事件。即事件从外向内传播。

事件冒泡(Event Bubbling):事件最开始由最具体的元素接收,然后逐级向上传播至最不具体的节点(文档)。即事件从内向外传播。

现代浏览器支持两种事件流,但默认情况下使用事件冒泡。可以通过 addEventListener 的第三个参数来指定事件处理程序是在捕获阶段还是冒泡阶段执行。

示例:

html 复制代码
<div id="outer">
  Outer Div
  <div id="inner">Inner Div</div>
</div>
<script>
  document.getElementById('outer').addEventListener('click', function(event) {
    console.log('Outer Div Clicked (Capturing)');
  }, true); // 捕获阶段
 
  document.getElementById('inner').addEventListener('click', function(event) {
    console.log('Inner Div Clicked (Bubbling)');
  }); // 默认为冒泡阶段
</script>
  1. 常见的事件类型

鼠标事件:

click:用户单击主鼠标按钮或按下在聚焦时按下回车键时触发。

dblclick:用户双击主鼠标按键触发。

mousedown:用户按下鼠标任意按键时触发。

mouseup:用户抬起鼠标任意按键时触发。

mousemove:鼠标在元素上移动时触发。

mouseover:鼠标进入元素时触发。

mouseout:鼠标离开元素时触发。

mouseenter:鼠标进入元素时触发,该事件不会冒泡。

mouseleave:鼠标离开元素时触发,该事件不会冒泡。

键盘事件:

keydown:按下键盘上任意键触发,如果按住不放,会重复触发此事件。

keypress:按下键盘上一个字符键时触发。

keyup:抬起键盘上任意键触发。

表单事件:

focus:元素获得焦点时触发。

blur:元素失去焦点时触发。

change:表单元素的值发生变化并失去焦点时触发。

input:表单元素的值发生变化时立即触发。

submit:表单提交时触发。

reset:表单重置时触发。

窗口事件:

load:页面或某个元素加载完成后触发。

unload:页面或某个元素卸载时触发。

resize:窗口或某个元素的大小发生变化时触发。

scroll:窗口或某个元素发生滚动时触发。

beforeunload:窗口关闭前触发,可以阻止关闭窗口。

其他事件:

error:发生错误时触发。

contextmenu:用户右键点击时触发。

copy、cut、paste:复制、剪切、粘贴事件。

drag、dragstart、dragend、dragover、drop:拖放事件。

示例:

html 复制代码
<input type="text" id="myInput">
<script>
  document.getElementById('myInput').addEventListener('input', function(event) {
    console.log('Input changed:', event.target.value);
  });
 
  window.addEventListener('resize', function(event) {
    console.log('Window resized:', window.innerWidth, 'x', window.innerHeight);
  });
 
  window.addEventListener('scroll', function(event) {
    console.log('Window scrolled:', window.scrollY);
  });
</script>
6. 事件委托

事件委托是一种优化事件处理的技术,通过将事件处理程序绑定到父元素上,利用事件冒泡的特性来处理子元素的事件。这样可以减少事件处理程序的数量,提高性能。

示例

html 复制代码
<ul id="list">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>
<script>
  document.getElementById('list').addEventListener('click', function(event) {
    if (event.target.tagName === 'LI') {
      console.log('Clicked item:', event.target.textContent);
    }
  });
</script>

案例

html 复制代码
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>onLoad事件</title>
	</head>
	<body onload="checkCookies()">
		<script type="text/javascript">
			function checkCookies () {
				if(navigator.cookieEnabled==true)
					alert("已启用Cookies");
					else
					alert("未启用Cookies");
			}
		</script>
		<p>提示框会告诉你,浏览器是否已启用Cookies。</p>
	</body>
</html>
html 复制代码
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>onchange事件</title>
		<script type="text/javascript">
			function myFunction(){
				var x=document.getElementById("fname");
				x.value=x.value.toUpperCase();
			}
		</script>
	</head>
	<body>
		请输入英文字符:<input type="text" id="fname" onchange="myFunction()"/>
		<p>当您离开输入字段时,会触发将输入文本转换为大写的函数。</p>
	</body>
</html>
html 复制代码
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>鼠标事件</title>
		<script type="text/javascript">
			function mouseOver(obj){
				obj.style.color="blue";
				obj.innerHTML="把鼠标移开"
			}
			function mouseOut(obj){
				obj.style.color="red";
				obj.innerHTML="把鼠标移到上面"
			}
			function mouseDown(obj){
				obj.style.backgroundColor="blue";
				obj.innerHTML="请释放鼠标按钮";
			}
			function mouseUp(obj){
				obj.style.backgroundColor="red";
				obj.innerHTML="请按下鼠标按钮";
			}
		</script>
	</head>
	<body>
		<div onmouseover="mouseOver(this)" onmouseout="mouseOut(this)" style="background-color: green;width: 120px;height: 20px;padding: 20px;color: #ffffff;">把鼠标移到上面</div>
		<br />
		<div onmousedown="mouseDown(this)" onmouseup="mouseUp(this)" style="background-color: green;width: 120px;height: 20px;padding: 20px;color: #ffffff;">请按下鼠标按钮</div>
	</body>
</html>
html 复制代码
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>键盘事件</title>
		<script type="text/javascript">
			function keyDown(){
				alert("你按下了按键");
				if(event.ctrlKey){
					alert("你按下了Ctrl键");
				}
			}
			function keyPress(){
				alert("你按下了键,并且释放了按键");
			}
		</script>
	</head>
	<body onkeydown="keyDown()" onkeypress="keyPress()">
	</body>
</html>
html 复制代码
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>图片轮播效果</title>
		<style type="text/css">
			*{
				margin: 0;
				padding: 0;
				text-decoration: none;
			}
			body{
				padding: 20px;
			}
			#container{
				position: relative;
				width: 600px;
				height: 400px;
				border:1px solid #333;
				overflow:hidden;
				margin-left: auto;
				margin-right: auto;
			}
			#list{
				position: absolute;
				z-index: 1;
				width: 4200px;
				height: 400px;
			}
			#list img{
				float: left;
				width: 600px;
				height: 400px;
			}
			#buttons{
				position: absolute;
				left: 250px;
				bottom: 20px;
				z-index: 2;
				height: 10px;
				width: 100px;
			}
			#buttons span{
				float: left;
				margin-right: 5px;
				width: 10px;
				height: 10px;
				border: 1px solid #fff;
				border-radius: 50%;
				background: #333;
				cursor: pointer;
			}
			#buttons.on{
				background: orangered;
			}
			.arrow{
				position: absolute;
				top: 180px;
				z-index: 2;
				display: none;
				width: 40px;
				height: 40px;
				font-size: 36px;
				font-weight: bold;
				line-height: 39px;
				text-align: center;
				color: #fff;
				background-color: RGBA(0,0,0,.3);
				cursor: pointer;
			}
			.arrow:hover{
				background-color: RGBA(0,0,0,.7);
			}
			#container:hover.arrow{
				display: block;
			}
			#prev{
				left: 20px;
			}
			#next{
				right: 20px;
			}
		</style>
		<script type="text/javascript">
			window.onload=function(){
				var container=document.getElementById('container');
				var list=document.getElementById('list');
				var buttons=document.getElementById('buttons').getElementsByTagName('span');
				var prev=document.getElementById('prev');
				var next=document.getElementById('next');
				var index=1;
				var timer;
				function animate(offset){
					var newLeft=parseInt(list.style.left)+offset;
					list.style.left=newLeft+'px';
					//无限滚动判断
					if(newLeft>-600){
						list.style.left=-3000+'px';
					}
					if(newLeft<-3000){
						list.style.left=-600+'px';
					}
				}	
				function play(){
					// 重复执行的定时器
					timer=setInterval(function(){
						next.onclick();
					},2000)
				}
				function stop(){
					clearInterval(timer);
				}
				function buttonsShow(){
					// 将之前的小圆点的样式清楚
					for(var i=0;i<buttons.length;i++){
						if(buttons[i].className=="on"){
							buttons[i].className="";
						}
					}
					// 数组从0开始,index需要减1
					buttons[index-1].className="on";
				}
				prev.onclick=function(){
					index-=1;
					if(index<1){
						index=5
					}
					buttonsShow();
					animate(600);
				};
				next.onclick=function(){
					index+=1;
					if(index>5){
						index=1
					}
					animate(-600);
					buttonsShow();
				};
				for(var i=0;i<buttons.length;i++){
					(function(i){
						buttons[i].onclick=function(){
							var clickIndex=parseInt(this.getAttribute('index'));
							var offset=600*(index-clickIndex);
							animate(offset);
							index=clickIndex;
							buttonsShow();
						}
					})(i)
				}
				container.onmouseover=stop;
				container.onmouseout=play;
				play();
			}
		</script>
	</head>
	<body>
	<div id="container">
		<div id="list" style="left: -600px;">
			<img src="img/p5.jpg" alt="5"/>
			<img src="img/p1.jpg" alt="1"/>
			<img src="img/p2.jpg" alt="2"/>
			<img src="img/p3.jpg" alt="3"/>
			<img src="img/p4.jpg" alt="4"/>
			<img src="img/p5.jpg" alt="5"/>
			<img src="img/p1.jpg" alt="5"/>
		</div>
		<div id="buttons">
			<span index="1" class="on"></span>
			<span index="2"></span>
			<span index="3"></span>
			<span index="4"></span>
			<span index="5"></span>
		</div>
			<a href="javascript:;" id="prev" class="arrow">&lt;</a>
			<a href="javascript:;" id="next" class="arrow">&gt;</a>
	</div>
	</body>
</html>
相关推荐
夕阳产业——JAVA,入坑=失业几秒前
泛型擦除是什么?
java·开发语言
阿猿先森6 分钟前
PyQt6+pyqtgraph折线图绘制显示
开发语言·python
legend_jz10 分钟前
【Linux】线程的互斥和同步
linux·运维·服务器·开发语言·笔记·学习·学习方法
l1384942745121 分钟前
Java综合练习
java·开发语言·算法
人机emmo_490372112233 分钟前
第4关 Java分支结构之Switch【Java 分支结构之 Switch:灵活的选择利器】
java·开发语言·python
重生之我是数学王子39 分钟前
QT 实现仿制 网络调试器(未实现连接唯一性) QT5.12.3环境 C++实现
开发语言·c++·qt
枫の准大一1 小时前
C++从零到满绩——类和对象(中)
开发语言·c++
HEX9CF1 小时前
【数字图像处理+MATLAB】通过 Roberts, Prewitt, Sobel, LoG 等算子实现图像边缘检测:使用 edge 函数
开发语言·matlab·edge
努力小贼1 小时前
Vue小项目(开发一个购物车)
前端·javascript·vue.js
凡人的AI工具箱1 小时前
40分钟学 Go 语言高并发实战:高性能缓存组件开发
开发语言·后端·缓存·架构·golang