逻辑运算符 #
一、运算符概述 #
逻辑运算符用于布尔逻辑运算,常用于条件判断和流程控制。Deno支持逻辑与、逻辑或、逻辑非以及空值合并运算符。
二、逻辑非(!) #
2.1 基本用法 #
typescript
console.log(!true); // false
console.log(!false); // true
console.log(!0); // true
console.log(!1); // false
console.log(!""); // true
console.log(!"hello"); // false
console.log(!null); // true
console.log(!undefined); // true
2.2 双重否定 #
将任意值转换为布尔值:
typescript
console.log(!!1); // true
console.log(!!0); // false
console.log(!!"hello"); // true
console.log(!!""); // false
console.log(!!null); // false
console.log(!!undefined); // false
console.log(!!{}); // true
console.log(!![]); // true
2.3 实际应用 #
typescript
const items: string[] = [];
// 检查数组是否为空
if (!items.length) {
console.log("数组为空");
}
// 检查变量是否有值
let value: string | null = null;
if (!value) {
console.log("值为空");
}
三、逻辑与(&&) #
3.1 基本用法 #
typescript
console.log(true && true); // true
console.log(true && false); // false
console.log(false && true); // false
console.log(false && false); // false
3.2 短路求值 #
如果第一个操作数为假值,则不会计算第二个操作数:
typescript
let count = 0;
false && count++;
console.log(count); // 0 (count++未执行)
true && count++;
console.log(count); // 1 (count++执行)
3.3 返回值 #
返回第一个假值或最后一个值:
typescript
console.log(1 && 2); // 2
console.log(0 && 2); // 0
console.log("hello" && "world"); // "world"
console.log("" && "world"); // ""
console.log(null && "world"); // null
console.log(undefined && "world"); // undefined
3.4 实际应用 #
typescript
// 条件执行
const user = { name: "Alice", admin: true };
user.admin && console.log("管理员权限");
// 可选属性访问
interface Config {
server?: {
port?: number;
};
}
const config: Config = {};
const port = config.server && config.server.port;
console.log(port); // undefined
// 使用可选链更简洁
const port2 = config.server?.port;
console.log(port2); // undefined
四、逻辑或(||) #
4.1 基本用法 #
typescript
console.log(true || true); // true
console.log(true || false); // true
console.log(false || true); // true
console.log(false || false); // false
4.2 短路求值 #
如果第一个操作数为真值,则不会计算第二个操作数:
typescript
let count = 0;
true || count++;
console.log(count); // 0 (count++未执行)
false || count++;
console.log(count); // 1 (count++执行)
4.3 返回值 #
返回第一个真值或最后一个值:
typescript
console.log(1 || 2); // 1
console.log(0 || 2); // 2
console.log("hello" || "world"); // "hello"
console.log("" || "world"); // "world"
console.log(null || "default"); // "default"
console.log(undefined || "default"); // "default"
4.4 实际应用 #
typescript
// 默认值
function greet(name: string) {
const displayName = name || "Guest";
console.log(`Hello, ${displayName}!`);
}
greet("Alice"); // Hello, Alice!
greet(""); // Hello, Guest!
// 配置默认值
interface Options {
timeout?: number;
retries?: number;
}
function fetchData(options: Options = {}) {
const timeout = options.timeout || 5000;
const retries = options.retries || 3;
console.log(`Timeout: ${timeout}ms, Retries: ${retries}`);
}
fetchData(); // Timeout: 5000ms, Retries: 3
fetchData({ timeout: 10000 }); // Timeout: 10000ms, Retries: 3
五、空值合并(??) #
5.1 基本用法 #
只有当左侧为 null 或 undefined 时才返回右侧:
typescript
console.log(null ?? "default"); // "default"
console.log(undefined ?? "default"); // "default"
console.log(0 ?? "default"); // 0
console.log("" ?? "default"); // ""
console.log(false ?? "default"); // false
console.log(NaN ?? "default"); // NaN
5.2 与||的区别 #
typescript
// || 会将假值视为需要默认值
console.log(0 || "default"); // "default"
console.log("" || "default"); // "default"
console.log(false || "default"); // "default"
// ?? 只检查null和undefined
console.log(0 ?? "default"); // 0
console.log("" ?? "default"); // ""
console.log(false ?? "default"); // false
5.3 实际应用 #
typescript
interface Config {
port?: number;
host?: string;
debug?: boolean;
}
function startServer(config: Config) {
const port = config.port ?? 3000;
const host = config.host ?? "localhost";
const debug = config.debug ?? false;
console.log(`Starting server at ${host}:${port}, debug: ${debug}`);
}
startServer({}); // Starting server at localhost:3000, debug: false
startServer({ port: 8080, debug: true }); // Starting server at localhost:8080, debug: true
startServer({ port: 0 }); // Starting server at localhost:0, debug: false
六、可选链(?.) #
6.1 基本用法 #
安全地访问深层嵌套属性:
typescript
interface User {
name: string;
address?: {
city?: string;
country?: string;
};
}
const user: User = { name: "Alice" };
// 传统方式
const city = user.address && user.address.city;
// 可选链
const city2 = user.address?.city;
console.log(city2); // undefined
// 多层可选链
const country = user.address?.country?.toUpperCase();
console.log(country); // undefined
6.2 函数调用 #
typescript
interface Options {
callback?: () => void;
}
function execute(options: Options) {
options.callback?.();
}
execute({ callback: () => console.log("Called!") }); // Called!
execute({}); // 无输出,不报错
6.3 数组访问 #
typescript
const arr: (number | undefined)[] = [1, undefined, 3];
console.log(arr[0]?.toFixed(2)); // "1.00"
console.log(arr[1]?.toFixed(2)); // undefined
console.log(arr[10]?.toFixed(2)); // undefined
七、逻辑赋值运算符 #
7.1 逻辑与赋值(&&=) #
只有当左侧为真值时才赋值:
typescript
let a = 10;
a &&= 20;
console.log(a); // 20
let b = 0;
b &&= 20;
console.log(b); // 0 (未赋值)
// 等价于
// a = a && 20;
7.2 逻辑或赋值(||=) #
只有当左侧为假值时才赋值:
typescript
let a = 0;
a ||= 10;
console.log(a); // 10
let b = 5;
b ||= 10;
console.log(b); // 5 (未赋值)
// 等价于
// a = a || 10;
7.3 空值合并赋值(??=) #
只有当左侧为 null 或 undefined 时才赋值:
typescript
let a: number | null = null;
a ??= 10;
console.log(a); // 10
let b = 0;
b ??= 10;
console.log(b); // 0 (未赋值,因为0不是null/undefined)
let c: string | undefined = undefined;
c ??= "default";
console.log(c); // "default"
7.4 实际应用 #
typescript
interface Cache {
[key: string]: string;
}
const cache: Cache = {};
function getData(key: string): string {
cache[key] ??= expensiveOperation(key);
return cache[key];
}
function expensiveOperation(key: string): string {
console.log(`Computing for ${key}...`);
return `value-${key}`;
}
console.log(getData("a")); // Computing for a... value-a
console.log(getData("a")); // value-a (使用缓存)
八、优先级 #
8.1 优先级顺序 #
从高到低:
!(逻辑非)??(空值合并)&&(逻辑与)||(逻辑或)
8.2 示例 #
typescript
// 逻辑非优先级最高
console.log(!false && true); // true
// 逻辑与优先于逻辑或
console.log(true || false && false); // true
console.log((true || false) && false); // false
// 空值合并与逻辑运算符不能混用(需要括号)
// console.log(null ?? undefined || "default"); // 语法错误
console.log((null ?? undefined) || "default"); // "default"
console.log(null ?? (undefined || "default")); // "default"
九、真值和假值 #
9.1 假值(Falsy) #
typescript
const falsyValues = [
false,
0,
-0,
0n,
"",
null,
undefined,
NaN
];
falsyValues.forEach(value => {
console.log(Boolean(value)); // 全部为false
});
9.2 真值(Truthy) #
除了假值以外的所有值:
typescript
const truthyValues = [
true,
1,
-1,
"hello",
[],
{},
function() {},
Infinity,
-Infinity
];
truthyValues.forEach(value => {
console.log(Boolean(value)); // 全部为true
});
十、实际应用场景 #
10.1 条件渲染 #
typescript
interface User {
name: string;
avatar?: string;
}
function renderUser(user: User | null) {
return user && `
<div>
<img src="${user.avatar ?? "/default-avatar.png"}" />
<span>${user.name}</span>
</div>
`;
}
console.log(renderUser(null)); // null
console.log(renderUser({ name: "Alice" })); // <div>...</div>
10.2 配置合并 #
typescript
interface Config {
host?: string;
port?: number;
timeout?: number;
debug?: boolean;
}
const defaultConfig: Required<Config> = {
host: "localhost",
port: 3000,
timeout: 5000,
debug: false
};
function createConfig(userConfig: Config = {}): Required<Config> {
return {
host: userConfig.host ?? defaultConfig.host,
port: userConfig.port ?? defaultConfig.port,
timeout: userConfig.timeout ?? defaultConfig.timeout,
debug: userConfig.debug ?? defaultConfig.debug
};
}
console.log(createConfig({ port: 8080 }));
// { host: "localhost", port: 8080, timeout: 5000, debug: false }
10.3 防御性编程 #
typescript
interface APIResponse {
data?: {
users?: Array<{
name: string;
email?: string;
}>;
};
error?: string;
}
function getUsers(response: APIResponse): string[] {
if (response.error) {
throw new Error(response.error);
}
return response.data?.users?.map(u => u.name) ?? [];
}
const response: APIResponse = {
data: {
users: [
{ name: "Alice", email: "alice@example.com" },
{ name: "Bob" }
]
}
};
console.log(getUsers(response)); // ["Alice", "Bob"]
十一、总结 #
本章学习了:
- 逻辑非(!)和双重否定(!!)
- 逻辑与(&&)和短路求值
- 逻辑或(||)和默认值
- 空值合并(??)
- 可选链(?.)
- 逻辑赋值运算符(&&=、||=、??=)
- 运算符优先级
- 真值和假值
下一章,我们将学习位运算符。
最后更新:2026-03-28