JavaScript 基础语法
本章将介绍 JavaScript 的基础语法,包括变量、数据类型和运算符。
变量
变量是存储数据的容器。在 JavaScript 中,有三种方式声明变量。
var 关键字
var 是 ES5 及之前版本使用的变量声明方式:
var name = "张三";
var age = 20;
特点:
- 函数作用域
- 存在变量提升
- 可以重复声明
let 关键字(推荐)
let 是 ES6 引入的变量声明方式:
let name = "张三";
let age = 20;
特点:
- 块级作用域
- 不存在变量提升(暂时性死区)
- 不能重复声明
let count = 1;
count = 2; // 可以重新赋值
// let count = 3; // 错误:不能重复声明
const 关键字(推荐)
const 用于声明常量,一旦赋值就不能修改:
const PI = 3.14159;
const SITE_NAME = "编程教程";
特点:
- 块级作用域
- 必须在声明时初始化
- 不能重新赋值
- 对于对象和数组,可以修改其内部属性
const person = { name: "张三", age: 20 };
person.age = 21; // 可以修改属性
// person = {}; // 错误:不能重新赋值
const arr = [1, 2, 3];
arr.push(4); // 可以添加元素
// arr = []; // 错误:不能重新赋值
变量命名规则
- 变量名只能包含字母、数字、下划线和美元符号
- 变量名不能以数字开头
- 不能使用 JavaScript 保留字作为变量名
- 区分大小写
// 合法的变量名
let userName = "张三";
let age1 = 20;
let _private = "私有";
let $element = document.getElementById("app");
let camelCase = "驼峰命名";
// 非法的变量名
// let 1name = "错误"; // 不能以数字开头
// let class = "类"; // 不能使用保留字
// let my-name = "错误"; // 不能包含连字符
变量命名习惯
// 驼峰命名法(推荐)
let firstName = "张三";
let lastName = "李四";
let isStudent = true;
// 常量使用全大写
const MAX_SIZE = 100;
const API_URL = "https://api.example.com";
// 描述性命名
let userCount = 0;
let isLoading = true;
数据类型
JavaScript 有两种数据类型:原始类型(Primitive)和引用类型(Reference)。
原始类型
1. 数值(Number)
let integer = 42; // 整数
let float = 3.14; // 浮点数
let negative = -10; // 负数
let scientific = 2.5e5; // 科学计数法(250000)
let infinity = Infinity; // 无穷大
let nan = NaN; // 非数字(Not a Number)
// 特殊数值
console.log(10 / 0); // Infinity
console.log(0 / 0); // NaN
console.log(Math.sqrt(-1)); // NaN
// 数值判断
console.log(Number.isNaN(NaN)); // true
console.log(Number.isFinite(Infinity)); // false
console.log(Number.isInteger(3.14)); // false
2. 字符串(String)
// 单引号
let name1 = '张三';
// 双引号
let name2 = "李四";
// 反引号(模板字符串,推荐)
let greeting = `你好,${name1}!`;
let message = `今天是${new Date().getFullYear()}年`;
// 转义字符
let str = "他说:\"你好\"";
let path = "C:\\Users\\Admin\\Documents";
let newline = "第一行\n第二行";
let tab = "列1\t列2";
3. 布尔值(Boolean)
let isActive = true;
let isDeleted = false;
// 布尔转换
console.log(Boolean(1)); // true
console.log(Boolean(0)); // false
console.log(Boolean("")); // false
console.log(Boolean("hello")); // true
console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false
console.log(Boolean([])); // true(空数组为真)
console.log(Boolean({})); // true(空对象为真)
4. undefined
变量声明但未赋值:
let undefinedVar;
console.log(undefinedVar); // undefined
function test() {
// 没有 return 语句
}
console.log(test()); // undefined
5. null
表示空值:
let empty = null;
console.log(empty); // null
// 区分 null 和 undefined
console.log(null === undefined); // false(类型不同)
console.log(null == undefined); // true(值相等)
引用类型
1. 对象(Object)
let person = {
name: "张三",
age: 20,
isStudent: true
};
console.log(person.name); // 张三
console.log(person["age"]); // 20
2. 数组(Array)
let fruits = ["苹果", "香蕉", "橙子"];
console.log(fruits[0]); // 苹果
3. 函数(Function)
let greet = function() {
return "你好!";
};
typeof 操作符
console.log(typeof 42); // "number"
console.log(typeof 3.14); // "number"
console.log(typeof "hello"); // "string"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof null); // "object"(历史 bug)
console.log(typeof {}); // "object"
console.log(typeof []); // "object"
console.log(typeof function(){}); // "function"
类型转换
隐式转换
// 字符串连接
console.log("5" + 3); // "53"(数字转字符串)
console.log("5" - 3); // 2(字符串转数字)
console.log("5" * "2"); // 10(都转数字)
// 布尔转换
console.log(true + 1); // 2
console.log(false + 1); // 1
// 特殊转换
console.log("" == false); // true
console.log("" === false); // false
显式转换
// 转字符串
String(123); // "123"
(123).toString(); // "123"
String(true); // "true"
// 转数字
Number("123"); // 123
Number("12.34"); // 12.34
Number("hello"); // NaN
Number(""); // 0
Number(true); // 1
Number(false); // 0
Number(null); // 0
Number(undefined); // NaN
// 转整数
parseInt("123"); // 123
parseInt("12.34"); // 12
parseInt("10", 2); // 2(二进制)
parseInt("0x10"); // 16(十六进制)
// 转浮点数
parseFloat("3.14"); // 3.14
parseFloat("3.14.15"); // 3.14
// 转布尔值
Boolean(1); // true
Boolean(0); // false
Boolean(""); // false
Boolean("0"); // true
运算符
1. 算术运算符
let a = 10;
let b = 3;
console.log(a + b); // 13 - 加法
console.log(a - b); // 7 - 减法
console.log(a * b); // 30 - 乘法
console.log(a / b); // 3.333... - 除法
console.log(a % b); // 1 - 取余
console.log(a ** b); // 1000 - 幂运算
// 自增/自减
let x = 5;
console.log(++x); // 6(先加后用)
console.log(x++); // 6(先用后加)
console.log(--x); // 5(先减后用)
console.log(x--); // 5(先用后减)
2. 赋值运算符
let x = 10;
x += 5; // x = 15
x -= 3; // x = 12
x *= 2; // x = 24
x /= 2; // x = 12
x %= 5; // x = 2
x **= 2; // x = 4
3. 比较运算符
console.log(5 == 5); // true - 等于(类型转换)
console.log(5 == "5"); // true - 字符串转数字
console.log(5 === 5); // true - 严格等于
console.log(5 === "5"); // false - 类型不同
console.log(5 != 3); // true - 不等于
console.log(5 !== "5"); // true - 严格不等于
console.log(5 > 3); // true
console.log(5 < 3); // false
console.log(5 >= 5); // true
console.log(5 <= 3); // false
4. 逻辑运算符
// AND(&&):两边都为 true 才为 true
console.log(true && true); // true
console.log(true && false); // false
console.log(false && false); // false
// OR(||):任意一边为 true 就为 true
console.log(true || false); // true
console.log(false || false); // false
// NOT(!):取反
console.log(!true); // false
console.log(!false); // true
// 短路求值
console.log(true || console.log("不会执行"));
console.log(false && console.log("不会执行"));
// 实际应用
let name = "";
let displayName = name || "匿名用户";
console.log(displayName); // "匿名用户"
// 替代三元运算符
let score = 85;
score >= 60 && console.log("及格"); // 及格
5. 条件运算符(三元运算符)
let age = 20;
let status = age >= 18 ? "成年人" : "未成年人";
console.log(status); // "成年人"
// 嵌套使用
let grade = 85;
let result = grade >= 90 ? "A"
: grade >= 80 ? "B"
: grade >= 60 ? "C"
: "D";
console.log(result); // "B"
6. 位运算符
// AND(&)
console.log(5 & 3); // 1(0101 & 0011 = 0001)
// OR(|)
console.log(5 | 3); // 7(0101 | 0011 = 0111)
// XOR(^)
console.log(5 ^ 3); // 6(0101 ^ 0011 = 0110)
// NOT(~)
console.log(~5); // -6
// 左移(<<)
console.log(5 << 1); // 10
// 右移(>>)
console.log(5 >> 1); // 2
// 无符号右移(>>>)
console.log(-5 >>> 0); // 4294967291
7. 空值合并运算符
// ??:当左侧为 null 或 undefined 时使用右侧值
let a = null ?? "默认值"; // "默认值"
let b = undefined ?? "默认值"; // "默认值"
let c = "" ?? "默认值"; // ""(空字符串不是 null/undefined)
let d = 0 ?? "默认值"; // 0(0不是 null/undefined)
let e = false ?? "默认值"; // false
// ||:当左侧为假值时使用右侧值
let f = "" || "默认值"; // "默认值"
let g = 0 || "默认值"; // "默认值"
let h = false || "默认值"; // "默认值"
8. 可选链操作符
let user = { profile: { name: "张三" } };
// 传统写法
let name = user && user.profile && user.profile.name;
// 可选链
let name2 = user?.profile?.name; // "张三"
let city = user?.address?.city; // undefined(不会报错)
// 方法调用
let result = user?.getName?.(); // undefined(方法不存在)
运算符优先级
// 优先级从高到低
// () > 一元运算符 > ** > * / % > + - > 比较运算符
// > && > || > 条件运算符 > 赋值运算符
// 示例
let result = 2 + 3 * 4; // 14(先乘后加)
result = (2 + 3) * 4; // 20(括号优先)
let isValid = 5 > 3 && 2 < 4; // true
字符串方法
let str = "Hello, World!";
// 大小写转换
console.log(str.toUpperCase()); // "HELLO, WORLD!"
console.log(str.toLowerCase()); // "hello, world!"
// 字符串长度
console.log(str.length); // 13
// 查找子串
console.log(str.indexOf("World")); // 7
console.log(str.indexOf("world")); // -1(未找到)
console.log(str.includes("World")); // true
console.log(str.startsWith("Hello")); // true
console.log(str.endsWith("!")); // true
// 提取子串
console.log(str.slice(0, 5)); // "Hello"
console.log(str.substring(7, 12)); // "World"
console.log(str.substr(7, 5)); // "World"
// 替换
console.log(str.replace("World", "JavaScript")); // "Hello, JavaScript!"
console.log(str.replaceAll("o", "O")); // "HellO, WOrld!"
// 分割
let csv = "apple,banana,orange";
console.log(csv.split(",")); // ["apple", "banana", "orange"]
// 去除空白
let text = " hello ";
console.log(text.trim()); // "hello"
console.log(text.trimStart()); // "hello "
console.log(text.trimEnd()); // " hello"
// 填充
console.log("5".padStart(3, "0")); // "005"
console.log("5".padEnd(3, "0")); // "500"
小结
本章我们学习了:
- 变量声明(var、let、const)
- 各种数据类型(数值、字符串、布尔值、undefined、null)
- typeof 操作符和类型转换
- 各种运算符(算术、赋值、比较、逻辑、条件、位运算)
- 字符串常用方法
练习
- 声明变量存储你的名字、年龄和是否在职
- 将字符串 "123.45" 转换为数字并计算其四舍五入
- 使用模板字符串拼接多个变量的值
- 编写代码判断一个年份是否是闰年
- 交换两个变量的值(不借助第三个变量)