JavaScript 基础

JavaScript 教程

网页的四层结构

网页由四层信息构成,共同实现功能与展示效果:

image

  • 内容层:网页核心内容
  • 结构层:内容的组织形式,由标准语言描述
  • 表现层:内容的显示样式,由标准语言定义
  • 行为层:内容对事件的响应方式,由标准语言控制

各层对应的标准语言

层级 标准语言 说明
结构层 XML(可扩展标记语言)、XHTML(可扩展超文本标记语言) 描述网页内容的组织结构
表现层 CSS(层叠样式表) 定义网页内容的显示样式
行为层 DOM(文档对象模型)、ECMAScript(ECMA 制定的标准脚本语言) 控制网页的交互行为

补充:HTML 具备弱表现描述能力,CSS 可通过 hover 伪类实现简单响应行为。

什么是 JavaScript

  • JavaScript 是一种脚本语言,专为 HTML 页面添加交互性设计。
  • 通常直接嵌入 HTML 页面,无需预先编译,属于解释型语言。
  • 无需购买许可证,可免费使用。

JavaScript 的组成

ECMAScript 是标准化的脚本程序语言规范,定义了基本语法,不与浏览器绑定。Flash 中的 ActionScript 及 JavaScript 均是其具体实现。

JavaScript 能做什么

  • 为 HTML 页面添加动态内容,读写 HTML 元素。
  • 对事件作出反应,验证表单数据。
  • 检测浏览器类型,创建 cookies。
  • 是互联网上最流行的脚本语言,支持所有主流浏览器。

如何在 HTML 中插入 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>导入js的方式1:行内式</title>
</head>
<body>
    <a onclick="return confirm('are you sure')" href="../1.html" style="color: red;">返回</a>
</body>
</html>
  • 效果:点击链接会弹出确认框,点击“取消”不跳转,点击“确定”跳转到 ../1.html 页面。

image

image

嵌入式(使用 script 标记对嵌入网页)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>导入js的方式2:嵌入式</title>
    <script>
        document.write("<p>hello world</p>")
    </script>
</head>
<body>
</body>
</html>
  • 效果:页面直接显示“hello world”。

image

链接式(通过 script 标记的 src 属性链接外部脚本文件)

步骤1:新建外部 JS 文件(如 index.js)

image

/**
 * 外部链接式
 */
/**
 * 函数
 */
function test() {
    alert("Hello JavaScript!")
}

/**
 * 调用
 */
test()

步骤2:在 HTML 中链接外部 JS 文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>导入js的方式3:链接式</title>
    <script src="../../scripts/index.js"></script>
</head>
<body>
</body>
</html>
  • 效果:页面加载时弹出“Hello JavaScript!”提示框。

image

  • 注意:script 标签不能使用单标签,导入时会将 JS 内容复制到 <script></script> 之间。

JavaScript 语言基础

JavaScript 变量

  • JavaScript 变量为弱类型,无特定类型限制,用 var/let/const 声明,可初始化为任意值,且能修改数据类型(不建议)。
  • 示例:
    var name = "Six Hang";
    var age = 28;
    var school = "CSU";
    var male = true;
    

变量命名规范

  • 第一个单词全小写,后续单词首字母大写(小驼峰命名法),如 sMyString
  • 首字符必须是字母、下划线(_)或美元符号($)。
  • 后续字符可包含字母、数字、下划线、美元符号。
  • 不能是关键字或保留字,对大小写敏感。
  • 不能包含空格、回车符或其他标点字符。

ES6 新特性:let 和 const

/**
 * js 中的变量,弱类型,用 var/let 声明
 * ES6 新特性: let 和 const
 * let 声明的变量,块级作用域
 * const 声明的变量,常量,不能修改
 */
var username = 'peppa'
console.log("username变量类型:", typeof username)
// 可以随意改变变量中所存储的数据类型,当然为了程序规范应该避免这样操作
username = 100
console.log("username变量类型:", typeof username)

for (var i = 0; i < 10; i++) {}
// i 可以在循环外访问
console.log("迭代完成,i = ", i)
// 若用 let 声明变量,则 i 只能在循环内部访问
for (let j = 0; j < 10; j++) {}
// console.log("迭代完成,j = ", j) // 报错,块级作用域只在块级有效

const PI = 3.14
// PI = 3.1415 // 不能修改常量,会报错
  • console.log 用于在浏览器控制台输出内容。

image
image
image
image
image

变量命名原则(非法示例)

  • var 5zhao; // 数字开头,非法
  • var tang's; // 包含单引号,非法字符
  • var this; // 使用关键字,非法

运算符

运算符用于对一个或多个值进行运算,产生结果值,参与运算的值称为操作数。

算术运算符

Operator Description Example Result
+ 加法 x=2, y=2 x+y = 4
- 减法 x=5, y=2 x-y = 3
* 乘法 x=5, y=4 x*y = 20
/ 除法 15/5, 5/2 3, 2.5
% 取模(余数) 5%2, 10%8, 10%2 1, 2, 0
++ 自增 x=5, x++ x=6
-- 自减 x=5, x-- x=4

赋值运算符

Operator Example Is The Same As
= x=y x=y
+= x+=y x=x+y
-= x-=y x=x-y
*= x*=y x=x*y
/= x/=y x=x/y
%= x%=y x=x%y

比较运算符

Operator Description Example
== 等于(仅比较值) 58 → false;x=5, y="5" → xy → true
=== 全等(比较值和类型) x=5, y="5" → x===y → false
!= 不等于 5!=8 → true
> 大于 5>8 → false
< 小于 5<8 → true
>= 大于等于 5>=8 → false
<= 小于等于 5<=8 → true

逻辑运算符

  • JS 中逻辑运算返回短路处的值。
  • 示例:let resValue = 100 || ("peppa" && "") → 100(或运算遇 true 短路,返回第一个值)。
Operator Description Example
&& 逻辑与 x=6, y=3 → (x<10 && y>1) → true
|| 逻辑或 x=6, y=3 → (x5 || y5) → false
! 逻辑非 x=6, y=3 → !(x==y) → true

字符串连接运算符

  • + 运算符连接两个或多个字符串。
  • 示例:
    txt1 = "What a very"
    txt2 = "nice day!"
    txt3 = txt1 + txt2 // txt3 结果为 "What a verynice day!"
    

条件运算符

  • 语法:var 变量名 = (条件) ? 值1 : 值2
  • 示例:
    greeting = (visitor == "PRES") ? "Dear President " : "Dear "
    
    • 若 visitor 等于 "PRES",greeting 为 "Dear President ";否则为 "Dear "。

JavaScript 中的数据类型

数据类型 布尔值判断规则 说明
String(字符串) 非空串为 true,空串为 false 用单引号或双引号包裹
number(数值) 0 为 false,非 0 为 true 不区分整型和浮点型
boolean(布尔) true/false 不能用引号包裹(否则为字符串)
object(对象) null 为 false,非 null 为 true 复杂数据类型
undefined(未定义) false 未初始化的变量值为 undefined
NaN(非数字) false let result = "abc" * 100 → NaN

字符串(String)

字符串定义

  • 由零个或多个字符构成,字符可包括字母、数字、标点符号、空格。
  • 必须放在单引号或双引号中,可使用转义字符 \ 输出特殊字符。
  • 示例:
    var course = "data structure";
    var case = 'the birthday"19801106"';
    var score = " run time 3\' 15\""; // 转义字符使用
    

JavaScript 中的转义字符

Code Outputs
' 单引号
" 双引号
& 和号
\ 反斜杠
\n 换行
\r 回车
\t 制表符
\b 退格
\f 换页

字符串对象常见属性和方法

定义示例字符串:var myString = "This is a sample";

属性/方法 说明 示例 结果
length 返回字符串长度 var name = "Six tang"; name.length 11
charAt(index) 返回指定位置的字符(索引从 0 开始) myString.charAt(2) "i"
charCodeAt(index) 返回指定位置字符的 10 进制 ASCII 码 myString.charCodeAt(2) 105
indexOf(substr) 返回子串在字符串中的起始位置 myString.indexOf("is") 2
substr(start, length) 截取字符串(起始位置,长度) myString.substr(10, 3) "sam"
substring(start, end) 截取字符串(起始位置,结束位置,不包含结束位置) myString.substring(5, 9) "is a"
split(separator) 按分隔符将字符串分割为数组 var a = myString.split(" ") a[0]="This", a[1]="is", a[2]="a", a[3]="sample"
replace(old, new) 替换字符串中的子串 myString.replace("sample", "apple") "This is a apple"
toLowerCase() 转换为小写字母 myString.toLowerCase() "this is a sample"

数值型(number)

  • 不区分整型和浮点型,无需用引号包裹。

  • 示例:

    var num1 = 23.45;
    var num2 = 76;
    var num3 = -9e5; // 科学计数法,等价于 -900000
    alert(num1 + " " + num2 + " " + num3); // 输出 "23.45 76 -900000"
    

    image

  • 字符串转数值:

    let number1 = "200";
    let number2 = "100";
    let number3 = "50.20";
    alert(parseInt(number1) + parseInt(number2) + parseFloat(number3) + number1 + " " + number2 + " " + number3);
    

    image

布尔型(boolean)

  • 取值仅为 truefalse,不能用引号包裹(否则为字符串)。
  • typeof() 可判断数据类型:
    var married = true;
    document.write(typeof(married) + "<br />"); // 输出 "boolean"
    married = "true";
    document.write(typeof(married)); // 输出 "string"
    

数组(array)

数组声明

  • []new Array() 声明,可指定长度。
  • 示例:
    let list1 = []
    let list2 = new Array(10) // 创建长度为 10 的数组
    list2[9] = 100
    console.log("list1:", list1)
    console.log("list2:", list2)
    
    image

数组的常用属性和方法

属性/方法 说明 示例 结果
length 获取数组长度 var Map = new Array("China", "USA", "Britain"); Map.length 3
toString() 将数组转为字符串 Map.toString() "China,USA,Britain"
push(item) 向数组末尾添加元素,返回新长度 let list = []; list.push(1); list.push(2); 数组变为 [1,2]
pop() 删除并返回数组最后一个元素 list.pop() 2,数组变为 [1]
shift() 删除并返回数组第一个元素 list.shift() 1,数组变为 []
unshift(items) 向数组开头添加元素,返回新长度 list.unshift(1,2,3) 3,数组变为 [1,2,3]
splice(start, deleteCount, items) 删除元素并添加新元素 let list = ['peppa', 'lili', 'lucy']; list.splice(1,1,'lala','lulu') 数组变为 ['peppa', 'lala', 'lulu', 'lucy']

数组作为栈使用

let list = [];
list.push(1);
list.push(2);

console.log(list.pop());
console.log(list.pop());

image

数组作为队列使用

let list = [];
list.push(1);
list.push(2);

console.log(list.shift());
console.log(list.shift());

image

数组作为双端队列使用

let list = [];
// unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度。
console.log(list.unshift(1, 2, 3));
console.log(list);

// push() 方法可向数组的末尾添加一个或更多元素,并返回新的长度。
console.log(list.push(4, 5, 6));
console.log(list);

// pop() 方法从数组中删除最后一个元素,并返回该元素的值。
console.log(list.pop());
console.log(list);

// shift() 方法从数组中删除第一个元素,并返回该元素的值。
console.log(list.shift());
console.log(list);

image

splice

删除某个元素,添加元素。第一个参数为删除的起始位置,第二个参数为删除的个数,第三个参数以后为添加的元素

let list = ['peppa', 'lili', 'lucy'];
// splice 删除某个元素,添加元素 第一个参数为删除的起始位置,第二个参数为删除的个数,第三个参数为添加的元素
list.splice(1, 1, 'lala', 'lulu') // 删除下标为1的元素,添加两个元素
console.log(list)
list.splice(2, 2, 'lala', 'lulu') // 删除下标为2开始的2个元素,添加两个元素
console.log(list)

image

set 集合

  • 无序不重复的集合。
  • 示例:
    let set = new Set();
    set.add(1);
    set.add(2);
    set.add(3);
    set.add(4);
    console.log(set.size); // 4
    set.delete(2);
    console.log(set.size); // 3
    set.forEach(item => console.log(item)); // 1, 3, 4
    
    image

map

  • 键值对集合,键可以是任意类型。
  • 示例:
    let map = new Map();
    map.set('name', 'peppa');
    map.set('age', 18);
    map.set('sex', 'female');
    console.log(map.get('name')); // "peppa"
    console.log(map.has('name')); // true
    map.delete('name');
    console.log(map.size); // 2
    map.forEach((value, key) => {
      console.log(key, value); // "age 18", "sex female"
    });
    
    image

JavaScript 中的语句

条件语句

用于根据条件判断执行不同的代码块,包括 if 语句、if else 语句和 switch 语句。

if else 语句

var d = new Date();
var time = d.getHours();
if (time < 10) {
    document.write("<b>Good morning</b>");
} else if (time > 10 && time < 16) {
    document.write("<b>Good day</b>");
} else {
    document.write("<b>Hello World!</b>");
}

switch 语句

evalue = parseInt(prompt("请输入1-4对我们的服务做出评价",""));
switch(evalue){
    case 1: document.write("非常满意"); break; // break 防止穿透
    case 2: document.write("满意"); break;
    case 3: document.write("一般"); break;
    case 4: document.write("不满意"); break;
    default: document.write("您的输入有误!");
}

image

image

循环语句

用于重复执行一段代码,包括 while 循环、for 循环、for…in 语句。

while 循环

var i = 0;
while (i < 10) {
    document.write(i + "<br>");
    i++;
}

image

for 循环(九九乘法表)

for (var i = 1; i < 10; i++) { // 乘法表一共九行
    document.write("<tr>"); // 每行是 table 的一行
    for (j = 1; j < 10; j++) { // 每行都有9个单元格
        if (j <= i) { // 有内容的单元格
            document.write("<td style='border:2px solid #004B8A; background: white;'>" + i + "*" + j + "=" + (i * j) + "&nbsp;&nbsp;&nbsp;&nbsp;</td>");
        } else { // 没有内容的单元格
            document.write("<br>");
            break;
        }
    }
    document.write("</tr>");
}

image

for…in 语句(遍历对象/数组)

在有些情况下,开发者根本没有办法预知对象的任何信息,更谈不上控制循环的次数。这个时候用for…in语句可以很好的解决这个问题。

var x;
var mycars = new Array();
mycars[0] = "Saab";
mycars[1] = "Volvo";
mycars[2] = "BMW";
for (x in mycars) {
    document.write(mycars[x] + "<br />");
}

image

函数

函数是可重用的代码块,用于完成特定功能,可接收参数并返回结果。

函数定义语法

function functionname(arg1, arg2, ..., argX) {
    statements;
    [return [expression];] // 可选,返回结果
}

函数调用示例

示例1:带参数,无返回值

function myName(sName) {
    alert("Hello" + sName);
}
// 调用
myName("six-tang"); // 弹出 "Hellosix-tang"

image

示例2:带参数,有返回值

与其他编程语言一样,函数在执行过程中只要执行完return语句就会停止继续执行函数体中的代码,因此return语句后的代码都不会执行。下例中函数中的alert()语句就永远都不会执行。

function fnSum(iNum1, iNum2) {
    return iNum1 + iNum2;
    alert(iNum1 + iNum2); // 永远不会执行(return 后代码终止)
}
console.log(fnSum(10, 20)); // 输出 30

image

示例3:多 return 语句

一个函数中有时可以包含多个return语句,但每次只有一个会被执行,例如:

function substr(iNum1, iNum2) {
    if (iNum1 >= iNum2) {
        return iNum1 - iNum2;
    } else {
        return iNum2 - iNum1;
    }
}
alert(substr(10, 5)); // 弹出 5

image

示例4:无参数 return 语句(退出函数)

如果函数本身没有返回值,但又希望在某些时候退出函数体,则可以调用无参数的return语句来随时返回函数体,例如:

function myName(sName) {
    if (myName == "bye") {
        alert("Goodbye");
        return;
    }
    alert("Hello" + sName);
}
myName("bye"); // 弹出 "Goodbye"

image

ES6 函数新特性

箭头函数

  • 简洁写法,不绑定自身 this,继承外层作用域的 this

  • 示例:

    // 普通函数
    function add(a, b) {
        return a + b;
    }
    // 箭头函数(无大括号时直接返回表达式结果)
    const addArrow = (a, b) => a + b;
    // 单个参数可省略括号
    const addArrow2 = a => a + 1;
    // 多句代码需加大括号和 return
    const addArrow3 = (a, b) => {
        console.log("a = ", a);
        console.log("b = ", b);
        return a + b;
    };
    

    image

  • 注意:对象方法中不建议使用箭头函数(this 指向父级):

    let car = new Object();
    car.color = 'red';
    car.type = 'SUV';
    car.brand = 'Benz';
    car.run = function() {
        console.log(`${this.color}:${this.brand}:${this.type} is running...`);
    };
    car.run2 = () => {
        console.log(`${this.color}:${this.brand}:${this.type} is running...`); // this 指向父级为 window,属性 undefined
    };
    car.run(); // 正常输出
    car.run2(); // 输出 "undefined:undefined:undefined is running..."
    

    image

参数默认值

// ES6 前(短路运算实现默认值)
function add(num1, num2) {
    num1 = num1 || 0;
    num2 = num2 || 0;
    return num1 + num2;
}
// ES6 新特性(直接指定默认值)
function add(num1 = 0, num2 = 0) {
    return num1 + num2;
}
// 箭头函数 + 默认值
const add = (num1 = 0, num2 = 0) => num1 + num2;

可变参数

// 普通函数
function sum(a, ...number) {
    let sum = a;
    for (let number in number) {
        sum += number;
    }
    return sum;
}
// 箭头函数 + 可变参数
const sumArrow = (a, ...numbers) => {
    let sum = a;
    for (let number in numbers) {
        sum += number;
    }
    return sum;
};

全局变量(函数中未声明的变量)

function test() {
    username = 'peppa'; // 未声明,自动成为全局变量
}
test();
console.log(username); // 输出 "peppa"

image

对象

对象是特定实体的抽象,包含描述特性的属性(变量)和操作特性的方法(函数)。

对象的创建方式

new Object() 创建空对象

let car = new Object();
car.color = 'red';
car.type = 'SUV';
car.brand = 'Benz';
car.run = function() {
    console.log(`${this.color}:${this.brand}:${this.type} is running...`);
};
car.run(); // 输出 "red:Benz:SUV is running..."

image

函数工厂创建对象

function createCar(color, type, brand) {
    let car = new Object();
    car.color = color;
    car.type = type;
    car.brand = brand;
    car.run = function () {
        console.log(`${this.color}:${this.brand}:${this.type} is running...`);
    };
    return car;
}
let car1 = createCar("red", "car", "BMW");
car1.run(); // 输出 "red:BMW:car is running..."
let car2 = createCar("yellow", "bus", "Tesla");
car2.run(); // 输出 "yellow:Tesla:bus is running..."

image

构造方法创建对象

function Car(color, brand, type) {
    this.color = color;
    this.brand = brand;
    this.type = type;
    this.run = function () {
        console.log(`${this.color}:${this.brand}:${this.type} is running...`);
    };
}
var car1 = new Car('red', 'Benz', 'Sedan');
car1.run(); // 输出 "red:Benz:Sedan is running..."

image

对象直接量(字面量)创建

let name = 'peppa';
let age = 10;
let gender = "Female";
// 普通字面量
let peppa = {
    name: name,
    age: age,
    gender: gender,
    study: function () {
        console.log(`${this.name} is studying.`);
    }
};
peppa.study(); // 输出 "peppa is studying."

// ES6 新特性:对象字面量简写
let peppa2 = {
    name, // 等价 name: name
    age, // 等价 age: age
    gender, // 等价 gender: gender
    birthday: '2019-01-01',
    study() { // 方法简写,等价 study: function(){}
        console.log(`${this.name} is studying.`);
    }
};
peppa2.study(); // 输出 "peppa is studying."

image

原型 prototype 动态添加属性和方法

针对已经定义好的对象进行动态添加。

// 已定义的构造函数
function Car(color, brand, type) {
    this.color = color;
    this.brand = brand;
    this.type = type;
    this.run = function () {
        console.log(`${this.color}:${this.brand}:${this.type} is running...`);
    };
}
// 动态添加属性
Car.prototype.price = 10000;
// 动态添加方法
Car.prototype.show = function () {
    console.log(`${this.color}:${this.brand}:${this.type} is ${this.price}`);
};
var car = new Car('red', 'Benz', 'SUV');
car.price = 20000;
car.run(); // 输出 "red:Benz:SUV is running..."
car.show(); // 输出 "red:Benz:SUV is 20000"

image

ES6 新特性:class(语法糖)

class Person {
    // 构造方法与Java不一样,这儿的构造方法名与类名不一样
    constructor(name, age, gender) {
        this.name = name
        this.age = age
        this.gender = gender
    }

    // 方法
    greet() {
        return "Hello, my name is " + this.name + " and I am " + this.age + " years old"
    }

    // 静态方法
    static isAdult(age) {
        return age >= 18
    }
}

//JS 也支持继承
class Student extends Person {
    constructor(name, age, gender, grade) {
        // super 调用父类的构造方法
        super(name, age, gender)
        this.grade = grade
    }

    study() {
        return this.name + " is studying in grade " + this.grade
    }

    greet() {
        // 调用父类的方法
        return super.greet() + " I am in grade " + this.grade
    }
}

var person = new Person("Peppa", 10, "Female")
console.log(person.greet())

var student = new Student("Lily", 12, "Female", 5)
console.log(student.study())
console.log(student.greet())

console.log(Person.isAdult(16))
console.log(Student.isAdult(20))

image

迭代对象中的属性

for in 迭代

class Person {
    constructor(name, age, gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
    greet() {
        return "Hello, my name is " + this.name + " and I am " + this.age + " years old";
    }
}
var person = new Person("Peppa", 10, "Female");
for (var key in person) {
    console.log(key + ": " + person[key]);
}

image

for of 与解构赋值(ES6 新特性)

let list = [1, 2, 3, 4, 5];
// for of 迭代数组元素
for (let item of list) {
    console.log(item); // 依次输出 1,2,3,4,5
}
// 解构赋值:从数组中提取元素赋值给变量
let [a, b, c, d, e] = list;
console.log(a, b, c, d, e); // 输出 "1 2 3 4 5"

image

展开运算(ES6 新特性)

class Person {
    constructor(name, age, gender) {
        this.name = name
        this.age = age
        this.gender = gender
    }
    greet() {
        return "Hello, my name is " + this.name + " and I am " + this.age + " years old"
    }
}

let p = new Person("Peppa", 5, "girl")
// 展开运算
let p1 = {...p} // 创建一个对象,对象属性与 p 一致
let p2 = {...p, name: "Lily"} // 创建一个对象,对象属性与 p 一致,但 name 属性被修改
// 展开运算不会有方法
// console.log(p1.greet()) // 报错
console.log(p1)
console.log(p2)
let p3 = {...p, grade: 1} // 创建一个对象,对象属性与 p 一致,新增 grade 属性
console.log(p3)

image

posted @ 2025-11-25 16:49  Jing61  阅读(2)  评论(0)    收藏  举报