JavaScript中的字符串连接
字符串连接是指将两个或多个字符串连接在一起。
在JavaScript中,如果你在字符串和数字之间使用+,它会将它们作为字符串组合起来。
console.log("10" + 5); // 输出: "105"
动态类型转换
JavaScript是一种动态类型语言,这意味着:
- 你不需要声明变量的数据类型。
- 类型可以根据分配的值自动改变。
let value = "10" + 5; // value现在是一个字符串: "105"
JavaScript运算符
我们学习了不同类型的运算符,特别是:
NaN – 非数字
NaN代表Not a Number(非数字)。当计算没有产生有效数字时,它就会出现。
let result = "hello" * 5;
console.log(result); // NaN
前置和后置递增/递减
后置递增 (x++)
先使用当前值,然后递增。
let x = 5;
console.log(x++); // 输出: 5
console.log(x); // 输出: 6
前置递增 (++x)
先增加值,然后使用。
let x = 5;
console.log(++x); // 输出: 6
后置递减 (x--)
let y = 10;
console.log(y--); // 输出: 10
console.log(y); // 输出: 9
前置递减 (--y)
let y = 10;
console.log(--y); // 输出: 9
总结
以下是我今天学到的内容:
- 字符串连接将字符串和数字连接起来。
- JavaScript使用动态类型转换。
- NaN表示非数字。
- 算术运算符执行基本数学运算。
- 前置/后置递增和递减帮助我们轻松地增加或减少值。
深入理解JavaScript运算符和类型转换
1. 字符串连接详解
基本字符串连接
// 字符串与字符串连接
console.log("Hello" + " " + "World"); // "Hello World"
// 字符串与数字连接
console.log("Age: " + 25); // "Age: 25"
console.log("Score: " + 95.5); // "Score: 95.5"
// 多个值连接
let name = "Alice";
let age = 30;
let city = "Beijing";
console.log(name + " is " + age + " years old and lives in " + city);
// "Alice is 30 years old and lives in Beijing"
模板字符串(现代方法)
// 使用模板字符串(推荐)
let name = "Bob";
let age = 28;
console.log(`${name} is ${age} years old`); // "Bob is 28 years old"
// 多行字符串
let message = `
Hello ${name},
Welcome to our website!
Your age is: ${age}
`;
2. 动态类型转换深入
类型转换规则
// 数字转字符串
let num = 42;
let str = String(num); // "42"
let str2 = num.toString(); // "42"
// 字符串转数字
let strNum = "123";
let numFromStr = Number(strNum); // 123
let numFromStr2 = parseInt(strNum); // 123
let numFromStr3 = parseFloat("123.45"); // 123.45
// 布尔值转换
console.log(Boolean(1)); // true
console.log(Boolean(0)); // false
console.log(Boolean("")); // false
console.log(Boolean("hello")); // true
隐式类型转换
// 算术运算中的隐式转换
console.log("5" - 3); // 2 (字符串被转换为数字)
console.log("5" * 2); // 10
console.log("10" / 2); // 5
// 比较运算中的隐式转换
console.log("5" == 5); // true (宽松相等)
console.log("5" === 5); // false (严格相等)
// 逻辑运算中的隐式转换
console.log("hello" && "world"); // "world"
console.log("" || "default"); // "default"
3. NaN详解
NaN的特性
// NaN不等于任何值,包括它自己
console.log(NaN === NaN); // false
console.log(NaN == NaN); // false
// 检查NaN的正确方法
console.log(isNaN(NaN)); // true
console.log(Number.isNaN(NaN)); // true (推荐)
// 产生NaN的常见情况
console.log(0 / 0); // NaN
console.log(Math.sqrt(-1)); // NaN
console.log(parseInt("hello")); // NaN
console.log("hello" * 5); // NaN
处理NaN
function safeDivide(a, b) {
const result = a / b;
if (Number.isNaN(result)) {
return "无法计算";
}
return result;
}
console.log(safeDivide(10, 2)); // 5
console.log(safeDivide(10, 0)); // "无法计算"
4. 递增和递减运算符详解
前置和后置的区别
let a = 5;
let b = 5;
// 前置递增
console.log(++a); // 6 (先递增,再使用)
console.log(a); // 6
// 后置递增
console.log(b++); // 5 (先使用,再递增)
console.log(b); // 6
// 在表达式中使用
let x = 3;
let y = 2;
let result = ++x + y; // 4 + 2 = 6
console.log(result); // 6
console.log(x); // 4
let p = 3;
let q = 2;
let result2 = p++ + q; // 3 + 2 = 5
console.log(result2); // 5
console.log(p); // 4
实际应用场景
// 循环计数器
for (let i = 0; i < 5; i++) {
console.log(`第${i + 1}次迭代`);
}
// 数组索引
let arr = ['a', 'b', 'c'];
let index = 0;
console.log(arr[index++]); // 'a'
console.log(arr[index++]); // 'b'
console.log(index); // 2
// 计数器
let counter = 0;
function incrementCounter() {
return ++counter; // 返回递增后的值
}
console.log(incrementCounter()); // 1
console.log(incrementCounter()); // 2
5. 其他重要运算符
算术运算符
// 基本算术运算
console.log(10 + 5); // 15
console.log(10 - 5); // 5
console.log(10 * 5); // 50
console.log(10 / 5); // 2
console.log(10 % 3); // 1 (取余)
// 幂运算
console.log(2 ** 3); // 8
console.log(Math.pow(2, 3)); // 8
// 一元运算符
let num = 5;
console.log(+num); // 5 (转换为数字)
console.log(-num); // -5 (取负)
比较运算符
// 基本比较
console.log(5 > 3); // true
console.log(5 < 3); // false
console.log(5 >= 5); // true
console.log(5 <= 3); // false
// 相等比较
console.log(5 == "5"); // true (宽松相等)
console.log(5 === "5"); // false (严格相等)
console.log(5 != "6"); // true
console.log(5 !== "5"); // true
// 特殊值比较
console.log(null == undefined); // true
console.log(null === undefined); // false
console.log(NaN == NaN); // false
逻辑运算符
// 逻辑与 (&&)
console.log(true && true); // true
console.log(true && false); // false
console.log(false && true); // false
console.log(false && false); // false
// 逻辑或 (||)
console.log(true || true); // true
console.log(true || false); // true
console.log(false || true); // true
console.log(false || false); // false
// 逻辑非 (!)
console.log(!true); // false
console.log(!false); // true
console.log(!!true); // true (双重否定)
// 短路求值
let name = "";
let displayName = name || "Anonymous"; // "Anonymous"
console.log(displayName);
let user = { name: "Alice" };
let userName = user && user.name; // "Alice"
console.log(userName);
6. 赋值运算符
let x = 10;
// 基本赋值
x = 5;
// 复合赋值
x += 3; // 等同于 x = x + 3
console.log(x); // 8
x -= 2; // 等同于 x = x - 2
console.log(x); // 6
x *= 4; // 等同于 x = x * 4
console.log(x); // 24
x /= 3; // 等同于 x = x / 3
console.log(x); // 8
x %= 3; // 等同于 x = x % 3
console.log(x); // 2
x **= 3; // 等同于 x = x ** 3
console.log(x); // 8
7. 位运算符
// 位与 (&)
console.log(5 & 3); // 1 (101 & 011 = 001)
// 位或 (|)
console.log(5 | 3); // 7 (101 | 011 = 111)
// 位异或 (^)
console.log(5 ^ 3); // 6 (101 ^ 011 = 110)
// 位非 (~)
console.log(~5); // -6
// 左移 (<<)
console.log(5 << 1); // 10 (101 << 1 = 1010)
// 右移 (>>)
console.log(5 >> 1); // 2 (101 >> 1 = 10)
// 无符号右移 (>>>)
console.log(-5 >>> 1); // 2147483645
8. 条件(三元)运算符
// 基本语法:condition ? value1 : value2
let age = 20;
let status = age >= 18 ? "成年" : "未成年";
console.log(status); // "成年"
// 嵌套三元运算符
let score = 85;
let grade = score >= 90 ? "A" :
score >= 80 ? "B" :
score >= 70 ? "C" :
score >= 60 ? "D" : "F";
console.log(grade); // "B"
// 在函数中使用
function getMessage(user) {
return user ? `Hello, ${user.name}!` : "Hello, Guest!";
}
console.log(getMessage({ name: "Alice" })); // "Hello, Alice!"
console.log(getMessage(null)); // "Hello, Guest!"
9. 类型检查运算符
// typeof 运算符
console.log(typeof "hello"); // "string"
console.log(typeof 42); // "number"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof null); // "object" (这是JavaScript的一个已知bug)
console.log(typeof {}); // "object"
console.log(typeof []); // "object"
console.log(typeof function(){}); // "function"
// instanceof 运算符
console.log([] instanceof Array); // true
console.log({} instanceof Object); // true
console.log("hello" instanceof String); // false (原始类型)
console.log(new String("hello") instanceof String); // true
10. 实际应用示例
表单验证
function validateForm(data) {
let errors = [];
// 检查必填字段
if (!data.name || data.name.trim() === "") {
errors.push("姓名是必填项");
}
// 检查年龄
let age = parseInt(data.age);
if (isNaN(age) || age < 0 || age > 120) {
errors.push("请输入有效年龄");
}
// 检查邮箱
if (data.email && !data.email.includes("@")) {
errors.push("请输入有效邮箱地址");
}
return errors.length === 0 ? "验证通过" : errors;
}
console.log(validateForm({ name: "Alice", age: "25", email: "alice@example.com" }));
// "验证通过"
console.log(validateForm({ name: "", age: "invalid", email: "invalid-email" }));
// ["姓名是必填项", "请输入有效年龄", "请输入有效邮箱地址"]
计算器函数
function calculate(operation, a, b) {
// 确保输入是数字
a = Number(a);
b = Number(b);
if (isNaN(a) || isNaN(b)) {
return "请输入有效数字";
}
switch (operation) {
case "+":
return a + b;
case "-":
return a - b;
case "*":
return a * b;
case "/":
if (b === 0) {
return "除数不能为零";
}
return a / b;
case "%":
return a % b;
case "**":
return a ** b;
default:
return "不支持的运算";
}
}
console.log(calculate("+", 10, 5)); // 15
console.log(calculate("*", 3, 4)); // 12
console.log(calculate("/", 10, 0)); // "除数不能为零"
console.log(calculate("invalid", 1, 2)); // "不支持的运算"
总结
JavaScript的运算符和动态类型转换是语言的核心特性,理解这些概念对于编写高质量的JavaScript代码至关重要。
关键要点:
- 字符串连接:使用+运算符连接字符串,注意数字会被转换为字符串
- 动态类型:JavaScript会根据上下文自动转换数据类型
- NaN处理:使用Number.isNaN()检查NaN值
- 递增递减:前置运算符先计算后使用,后置运算符先使用后计算
- 运算符优先级:理解运算符的执行顺序
- 类型安全:在重要计算中使用严格相等(===)和类型检查
掌握这些概念将帮助你编写更加健壮和可预测的JavaScript代码。