JS進(jìn)階教程之作用域、函數(shù)、解構(gòu)賦值、數(shù)組方法
一、作用域與作用域鏈
1.1 作用域的類型
局部作用域
- 函數(shù)作用域:在函數(shù)內(nèi)部聲明的變量只能在函數(shù)內(nèi)部訪問(wèn)
function calculate(x, y) {
const result = x + y; // 函數(shù)作用域內(nèi)的變量
console.log(result);
return result;
}
calculate(10, 5); // 15
// console.log(result); // 報(bào)錯(cuò):result未定義
- 塊作用域:由
{}代碼塊創(chuàng)建的作用域
{
let blockScoped = "我在塊作用域內(nèi)";
const constantValue = "我也是";
console.log(blockScoped); // 正常訪問(wèn)
}
// console.log(blockScoped); // 報(bào)錯(cuò)
// console.log(constantValue); // 報(bào)錯(cuò)
// var 沒(méi)有塊作用域
if (true) {
var globalLike = "我實(shí)際上在全局作用域";
let trulyBlocked = "我確實(shí)在塊作用域";
}
console.log(globalLike); // 正常訪問(wèn)
// console.log(trulyBlocked); // 報(bào)錯(cuò)
總結(jié):
let聲明的變量會(huì)產(chǎn)生塊作用域,var不會(huì)產(chǎn)生塊作用域const聲明的常量也會(huì)產(chǎn)生塊作用域- 不同代碼塊之間的變量無(wú)法互相訪問(wèn)
- 推薦使用
let或const
注:開(kāi)發(fā)中let和const經(jīng)常不加區(qū)分的使用,如果擔(dān)心某個(gè)值會(huì)不小被修改時(shí),則只能使用const聲明成常量。
全局作用域
最外層的作用域,任何地方都可以訪問(wèn)
const globalVar = "我是全局變量";
function accessGlobal() {
console.log(globalVar); // 可以訪問(wèn)
innerGlobal = "危險(xiǎn)!隱式全局變量"; // 沒(méi)有聲明關(guān)鍵字,成為全局變量
}
accessGlobal();
console.log(innerGlobal); // 可以訪問(wèn),但不推薦這種寫(xiě)法
總結(jié):
- 為
window對(duì)象動(dòng)態(tài)添加的屬性默認(rèn)也是全局的,不推薦!- 函數(shù)中未使用任何關(guān)鍵字聲明的變量為全局變量,不推薦?。?!
- 盡可能少的聲明全局變量,防止全局變量被污染
1.2 作用域鏈與變量查找
作用域鏈本質(zhì)上是JavaScript底層的變量查找機(jī)制:在函數(shù)被執(zhí)行時(shí),會(huì)優(yōu)先查找當(dāng)前函數(shù)作用域中查找變量,如果當(dāng)前作用域查找不到則會(huì)依次逐級(jí)查找父級(jí)作用域直到全局作用域
let outer = "全局變量";
function outerFunction() {
let middle = "外層函數(shù)變量";
function innerFunction() {
let inner = "內(nèi)層函數(shù)變量";
console.log(inner); // 1. 優(yōu)先查找當(dāng)前作用域
console.log(middle); // 2. 查找父級(jí)作用域
console.log(outer); // 3. 查找全局作用域
// console.log(notExist); // 報(bào)錯(cuò):所有作用域都找不到
}
innerFunction();
// console.log(inner); // 報(bào)錯(cuò):父作用域不能訪問(wèn)子作用域
}
outerFunction();
總結(jié):
- 嵌套關(guān)系的作用域串聯(lián)起來(lái)形成了作用域鏈
- 相同作用域鏈中按著從小到大的規(guī)則查找變量
- 子作用域能夠訪問(wèn)父作用域,父級(jí)作用域無(wú)法訪問(wèn)子級(jí)作用域
二、內(nèi)存管理與閉包
2.1 JavaScript垃圾回收機(jī)制
內(nèi)存生命周期
- 內(nèi)存分配:聲明變量、函數(shù)、對(duì)象時(shí)自動(dòng)分配
- 內(nèi)存使用:讀寫(xiě)內(nèi)存,使用變量、函數(shù)等
- 內(nèi)存回收:不再使用的內(nèi)存由垃圾回收器自動(dòng)回收
說(shuō)明:
- 全局變量一般不會(huì)回收(關(guān)閉頁(yè)面回收)
- 一般情況下局部變量的值,不用了,會(huì)被自動(dòng)回收掉
內(nèi)存泄漏:程序中分配的內(nèi)存由于某種原因程序未釋放或無(wú)法釋放叫做內(nèi)存泄漏
堆??臻g分配
- 棧(操作系統(tǒng)):由操作系統(tǒng)自動(dòng)分配釋放函數(shù)的參數(shù)值、局部變量等,基本數(shù)據(jù)類型放到棧里面
- 堆(操作系統(tǒng)):一般由程序員分配釋放,若程序員不釋放,由垃圾回收機(jī)制回收,復(fù)雜數(shù)據(jù)類型放到堆里面
// 棧內(nèi)存 - 存儲(chǔ)基本類型和引用地址
let num = 10; // 棧內(nèi)存
let str = "hello"; // 棧內(nèi)存
// 堆內(nèi)存 - 存儲(chǔ)復(fù)雜類型
let obj = { // obj在棧,{name: "John"}在堆
name: "John",
age: 30
};
let arr = [1, 2, 3]; // arr在棧,[1,2,3]在堆
垃圾回收算法
引用計(jì)數(shù)法(已逐漸淘汰)
跟蹤每個(gè)值被引用的次數(shù),引用次數(shù)為0,則清除
// 嵌套引用問(wèn)題
function problem() {
let objA = {};
let objB = {};
objA.ref = objB; // objB引用次數(shù): 1
objB.ref = objA; // objA引用次數(shù): 1
// 即使離開(kāi)作用域,引用計(jì)數(shù)不為0,無(wú)法回收
}
標(biāo)記清除法(現(xiàn)代瀏覽器主要使用)
從根對(duì)象(全局對(duì)象)開(kāi)始標(biāo)記所有可達(dá)對(duì)象,清除未被標(biāo)記的對(duì)象
2.2 閉包
閉包的基本概念
閉包 = 內(nèi)層函數(shù) + 外層函數(shù)的變量
// 基本閉包格式
function outer() {
let a = 100
function fn() {
console.log(a)
}
return fn
}
const fun = outer()
fun()
閉包的實(shí)際應(yīng)用
// 1. 數(shù)據(jù)私有化
// 統(tǒng)計(jì)函數(shù)調(diào)用次數(shù)
function count() {
let i = 0;
function fn() {
i++;
console.log(`函數(shù)被調(diào)用了${i}次`);
}
return fn;
}
const fun = count();
fun(); // 函數(shù)被調(diào)用了1次
fun(); // 函數(shù)被調(diào)用了2次
閉包的內(nèi)存泄漏問(wèn)題
// 可能造成內(nèi)存泄漏的示例
function leakyFunction() {
const largeData = new Array(1000000).fill("data");
return function() {
console.log("我持有l(wèi)argeData的引用");
// 即使largeData不再需要,由于閉包引用,無(wú)法被回收
};
}
// 解決方法:及時(shí)釋放引用
function safeFunction() {
const largeData = new Array(1000000).fill("data");
const innerFunction = function() {
console.log("使用數(shù)據(jù)");
};
// 使用后手動(dòng)解除引用
largeData = null;
return innerFunction;
}
總結(jié):
- 閉包 = 內(nèi)層函數(shù) + 外層函數(shù)的變量
- 閉包的作用:封閉數(shù)據(jù),實(shí)現(xiàn)數(shù)據(jù)私有,外部也可以訪問(wèn)函數(shù)內(nèi)部的變量
- 閉包可能會(huì)造成內(nèi)存泄漏
三、變量提升與函數(shù)提升
3.1 變量提升
// 變量提升示例
// 把所有var聲明的變量提升到當(dāng)前作用域的最前面
// 只提升聲明,不提升賦值
function fn() {
console.log(num); // undefined
var num = 10;
}
// 相當(dāng)于
function fn() {
var num;
console.log(num);
num = 10;
}
總結(jié):
- 變量在未聲明即被訪問(wèn)時(shí)會(huì)報(bào)語(yǔ)法錯(cuò)誤
- 變量在聲明之前即被訪問(wèn),變量的值為
undefinedlet聲明的變量不存在變量提升,推薦使用let- 變量提升出現(xiàn)在相同作用域當(dāng)中
- 實(shí)際開(kāi)發(fā)中推薦先聲明再訪問(wèn)變量
3.2 函數(shù)提升
// 函數(shù)聲明會(huì)提升
// 會(huì)把所有函數(shù)聲明提升到當(dāng)前作用域的最前面
// 只提升函數(shù)聲明,不提升函數(shù)調(diào)用
fn(); // 函數(shù)提升
function fn() {
console.log('函數(shù)提升');
}
// 函數(shù)表達(dá)式不會(huì)提升
fun(); // 錯(cuò)誤
var fun = function() {
console.log('函數(shù)表達(dá)式');
};
總結(jié):
- 函數(shù)提升能夠使函數(shù)的聲明調(diào)用更靈活
- 函數(shù)表達(dá)式不存在提升的現(xiàn)象
- 函數(shù)提升出現(xiàn)在相同作用域當(dāng)中
四、函數(shù)進(jìn)階
4.1 函數(shù)參數(shù)
默認(rèn)參數(shù)
<script>
// 設(shè)置參數(shù)默認(rèn)值
function sayHi(name="小明", age=18) {
document.write(`<p>大家好,我叫${name},我今年${age}歲了。</p>`);
}
// 調(diào)用函數(shù)
sayHi();
sayHi('小紅');
sayHi('小剛', 21);
</script>
動(dòng)態(tài)參數(shù)
arguments是函數(shù)內(nèi)部的偽數(shù)組,包含所有傳遞給函數(shù)的參數(shù)。
function getSum() {
let sum = 0;
for (let i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
console.log(sum);
}
getSum(2, 3, 4); // 9
總結(jié):
arguments是一個(gè)偽數(shù)組arguments的作用是動(dòng)態(tài)獲取函數(shù)的實(shí)參
剩余參數(shù)
function getSum(a, b, ...arr) {
let sum = 0;
for (let i = 0; i < arr.length; i++) {
sum += arr[i];
}
console.log(sum);
}
getSum(1, 2, 3, 4, 5); // 12
總結(jié):
...是語(yǔ)法符號(hào)(展開(kāi)運(yùn)算符),置于最末函數(shù)形參之前,用于獲取多余的實(shí)參- 借助
...獲取的剩余實(shí)參,是個(gè)真數(shù)組
展開(kāi)運(yùn)算符
展開(kāi)數(shù)組,將數(shù)組轉(zhuǎn)換為逗號(hào)分隔的參數(shù)序列,不會(huì)修改原數(shù)組,應(yīng)用于:求數(shù)組最大(?。┲?,合并數(shù)組等
// 展開(kāi)數(shù)組
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
// 1. 求最大(?。┲?
console.log(Math.max(...arr1)); // 3
console.log(Math.min(...arr1)); // 1
// 2. 合并數(shù)組
const arr = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6]
// 復(fù)制數(shù)組(淺拷貝)
const arrCopy = [...arr1];
// 展開(kāi)對(duì)象
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 }; // {a:1, b:2, c:3}
4.2 箭頭函數(shù)
基本語(yǔ)法
// 基本語(yǔ)法
const fn1 = () => {
console.log(123);
};
// 有參數(shù)的箭頭函數(shù)(單個(gè)參數(shù)可省略括號(hào))
const fn2 = x => {
console.log(x);
};
// 只有一行代碼時(shí),可省略大括號(hào)和return
const fn3 = x => x + x;
// 直接返回對(duì)象(需要用括號(hào)包裹)
const fn4 = (uname) => ({ uname: uname });
總結(jié):
- 箭頭函數(shù)屬于表達(dá)式函數(shù),因此不存在函數(shù)提升
- 箭頭函數(shù)只有一個(gè)參數(shù)時(shí)可以省略圓括號(hào)
()- 箭頭函數(shù)函數(shù)體只有一行代碼時(shí)可以省略花括號(hào)
{},并自動(dòng)做為返回值被返回
this 指向
箭頭函數(shù)的this指向是固定的,指向外層作用域的this
<script>
// 以前this的指向: 誰(shuí)調(diào)用的這個(gè)函數(shù),this 就指向誰(shuí)
// console.log(this) // window
// // 普通函數(shù)
// function fn() {
// console.log(this) // window
// }
// window.fn()
// // 對(duì)象方法里面的this
// const obj = {
// name: 'andy',
// sayHi: function () {
// console.log(this) // obj
// }
// }
// obj.sayHi()
// 2. 箭頭函數(shù)的this 是上一層作用域的this 指向
// const fn = () => {
// console.log(this) // window
// }
// fn()
// 對(duì)象方法箭頭函數(shù) this
// const obj = {
// uname: 'pink老師',
// sayHi: () => {
// console.log(this) // this 指向誰(shuí)? window
// }
// }
// obj.sayHi()
const obj = {
uname: 'pink老師',
sayHi: function () {
console.log(this) // obj
let i = 10
const count = () => {
console.log(this) // obj
}
count()
}
}
obj.sayHi()
</script>
箭頭函數(shù)參數(shù)
箭頭函數(shù)中沒(méi)有 arguments,只能使用 ... 動(dòng)態(tài)獲取實(shí)參
const getSum = (...arr) => {
let sum = 0;
for (let i = 0; i < arr.length; i++) {
sum += arr[i];
}
return sum;
};
console.log(getSum(2, 3, 5)); // 10
五、解構(gòu)賦值
5.1 數(shù)組解構(gòu)
數(shù)組解構(gòu)是將數(shù)組的單元值快速批量賦值給一系列變量的簡(jiǎn)潔語(yǔ)法
// 基本用法 const [max, min, avg] = [100, 60, 80]; console.log(max); // 100 // 變量交換 let a = 1, b = 2; [b, a] = [a, b]; console.log(a, b); // 2 1
5.2 數(shù)組解構(gòu)細(xì)節(jié)
// 1. 變量多,單元值少(未匹配的變量為undefined) const [a, b, c, d] = [1, 2, 3]; console.log(d); // undefined // 2. 變量少,單元值多(忽略多余的值) const [x, y] = [1, 2, 3]; // 3. 使用剩余參數(shù)收集多余的值 const [i, j, ...k] = [1, 2, 3, 4]; console.log(k); // [3, 4] // 4. 設(shè)置默認(rèn)值 const [o = 0, p = 0] = []; console.log(o, p); // 0 0 // 5. 跳過(guò)某些值 const [e, f, , h] = [1, 2, 3, 4]; console.log(e, f, h); // 1 2 4 // 6. 多維數(shù)組解構(gòu) const [l, m, [n, g]] = [1, 2, [3, 4]];
5.3 對(duì)象解構(gòu)
// 基本用法
const { uname, age } = { uname: 'pink老師', age: 18 };
// 變量重命名
const { uname: username, age } = { uname: 'pink老師', age: 18 };
// 解構(gòu)數(shù)組中的對(duì)象
const pig = [
{
name: '佩奇',
age: 6
}
];
const [{ name: uname, age }] = pig;
5.4 多級(jí)對(duì)象解構(gòu)
// 多級(jí)數(shù)組對(duì)象解構(gòu)
const pig = [
{
name: '佩奇',
family: {
mother: '豬媽媽',
father: '豬爸爸',
sister: '喬治'
},
age: 6
}
];
const [{ name, family: { mother, father, sister }, age }] = pig;
5.5 多級(jí)對(duì)象解構(gòu)案例
<body>
<script>
// 1. 這是后臺(tái)傳遞過(guò)來(lái)的數(shù)據(jù)
const msg = {
"code": 200,
"msg": "獲取新聞列表成功",
"data": [
{
"id": 1,
"title": "5G商用自己,三大運(yùn)用商收入下降",
"count": 58
},
{
"id": 2,
"title": "國(guó)際媒體頭條速覽",
"count": 56
},
{
"id": 3,
"title": "烏克蘭和俄羅斯持續(xù)沖突",
"count": 1669
},
]
}
// 需求1: 請(qǐng)將以上msg對(duì)象 采用對(duì)象解構(gòu)的方式 只選出 data 方面后面使用渲染頁(yè)面
// const { data } = msg
// console.log(data)
// 需求2: 上面msg是后臺(tái)傳遞過(guò)來(lái)的數(shù)據(jù),我們需要把data選出當(dāng)做參數(shù)傳遞給 函數(shù)
// const { data } = msg
// msg 雖然很多屬性,但是我們利用解構(gòu)只要 data值
function render({ data }) {
// const { data } = arr
// 我們只要 data 數(shù)據(jù)
// 內(nèi)部處理
console.log(data)
}
render(msg)
// 需求3, 為了防止msg里面的data名字混淆,要求渲染函數(shù)里面的數(shù)據(jù)名改為 myData
function render({ data: myData }) {
// 要求將 獲取過(guò)來(lái)的 data數(shù)據(jù) 更名為 myData
// 內(nèi)部處理
console.log(myData)
}
render(msg)
</script>
六、數(shù)組高階方法
6.1 forEach - 遍歷數(shù)組
forEach是數(shù)組的遍歷方法,適用于遍歷數(shù)組對(duì)象
const arr = ['red', 'green', 'pink'];
arr.forEach(function(item, index) {
console.log(item); // 元素值
console.log(index); // 索引
});
// 使用箭頭函數(shù)簡(jiǎn)寫(xiě)
arr.forEach((item, index) => {
console.log(item, index);
});
6.2 filter - 篩選數(shù)組
filter() 方法創(chuàng)建一個(gè)新的數(shù)組,新數(shù)組中的元素是通過(guò)檢查指定數(shù)組中符合條件的所有元素
const arr = [10, 20, 30];
// 使用函數(shù)表達(dá)式
const newArr1 = arr.filter(function(item) {
return item >= 20;
});
// 使用箭頭函數(shù)簡(jiǎn)寫(xiě)
const newArr2 = arr.filter(item => item >= 20);
console.log(newArr2); // [20, 30]
6.4 方法對(duì)比
| 方法 | 返回值 | 是否改變?cè)瓟?shù)組 | 用途 |
|---|---|---|---|
| forEach | undefined | 否 | 遍歷數(shù)組,執(zhí)行副作用 |
| filter | 新數(shù)組 | 否 | 篩選滿足條件的元素 |
| map | 新數(shù)組 | 否 | 轉(zhuǎn)換數(shù)組元素 |
| find | 第一個(gè)匹配元素 | 否 | 查找單個(gè)元素 |
| reduce | 累計(jì)值 | 否 | 累加或轉(zhuǎn)換數(shù)組 |
七、最佳實(shí)踐與注意事項(xiàng)
7.1 分號(hào)使用規(guī)則
// 必須加分號(hào)的情況
// 1. 立即執(zhí)行函數(shù)前
(function() {
console.log("IIFE");
})();
// 安全寫(xiě)法:前面加分號(hào)
;(function() {
console.log("安全的IIFE");
})();
// 2. 以數(shù)組開(kāi)頭的代碼前
const name = "JavaScript"
;[1, 2, 3].forEach(n => console.log(n))
// 3. 以模板字符串開(kāi)頭的代碼前
const greeting = "Hello"
`world`.toUpperCase() // 可能出錯(cuò)
7.2 作用域最佳實(shí)踐
// 1. 優(yōu)先使用const,其次是let
const PI = 3.14159;
let counter = 0;
// 2. 避免使用var
// ? 不好
var oldVar = "過(guò)時(shí)";
// ? 好
let modernLet = "現(xiàn)代";
const modernConst = "更現(xiàn)代";
// 3. 立即執(zhí)行函數(shù)創(chuàng)建私有作用域
(function() {
const privateVar = "外部無(wú)法訪問(wèn)";
// 模塊代碼
})();
// 4. 模塊化組織代碼
const Module = (function() {
let privateData = "私有";
return {
publicMethod: function() {
return privateData;
}
};
})();
7.3 閉包使用建議
// 1. 明確閉包的目的
function createCache() {
const cache = new Map();
return {
set: (key, value) => cache.set(key, value),
get: (key) => cache.get(key),
has: (key) => cache.has(key)
};
}
// 2. 避免不必要的閉包
function avoidClosure(arr) {
// ? 不必要的閉包
arr.forEach(function(item) {
console.log(item);
});
// ? 更簡(jiǎn)潔
arr.forEach(item => console.log(item));
}
// 3. 注意內(nèi)存管理
function createHeavyClosure() {
const largeData = new Array(1000000);
const useData = () => {
// 使用數(shù)據(jù)
};
// 使用完畢后解除引用
const cleanup = () => {
largeData.length = 0;
};
return { useData, cleanup };
}
總結(jié)
JavaScript的進(jìn)階特性提供了更強(qiáng)大、更靈活的編程能力。通過(guò)深入理解作用域、閉包、函數(shù)進(jìn)階特性等概念,可以編寫(xiě)出更簡(jiǎn)潔、更高效、更易維護(hù)的代碼。關(guān)鍵是要理解這些特性背后的原理,而不是僅僅記住語(yǔ)法。在實(shí)際開(kāi)發(fā)中,應(yīng)該根據(jù)具體場(chǎng)景選擇合適的技術(shù)方案,并遵循最佳實(shí)踐,避免常見(jiàn)的陷阱和性能問(wèn)題。
到此這篇關(guān)于JS進(jìn)階教程之作用域、函數(shù)、解構(gòu)賦值、數(shù)組方法的文章就介紹到這了,更多相關(guān)JS作用域、函數(shù)、解構(gòu)賦值、數(shù)組方法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
disable-devtool禁用web開(kāi)發(fā)者工具保護(hù)網(wǎng)頁(yè)源碼
這篇文章主要為大家介紹了disable-devtool禁用web開(kāi)發(fā)者工具保護(hù)網(wǎng)頁(yè)源碼的使用,防止源碼泄露保護(hù)網(wǎng)站源碼的最佳解決方案,一行代碼就可以搞定,有需要的可以學(xué)習(xí)參考下2023-11-11
js實(shí)現(xiàn)刷新頁(yè)面后回到記錄時(shí)滾動(dòng)條的位置【兩種方案可選】
本文主要介紹了頁(yè)面的div中有滾動(dòng)條,js實(shí)現(xiàn)刷新頁(yè)面后回到記錄時(shí)滾動(dòng)條的位置的兩種方案,需要的朋友可以看下2016-12-12
JavaScript正則表達(dá)式匹配 div style標(biāo)簽
這篇文章主要介紹了JavaScript正則表達(dá)式匹配<div><style>標(biāo)簽 的相關(guān)資料,需要的朋友可以參考下2016-03-03
VSCode 添加自定義注釋的方法(附帶紅色警戒經(jīng)典注釋風(fēng)格)
這篇文章主要介紹了VSCode 添加自定義注釋的方法(附帶紅色警戒經(jīng)典注釋風(fēng)格),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08
基于BootStrap柵格欄系統(tǒng)完成網(wǎng)站底部版權(quán)信息區(qū)
網(wǎng)站底部版權(quán)信息區(qū)可以用bootstrap的“柵格系統(tǒng)”完成,下面給大家分享一個(gè)未經(jīng)處理的底部版權(quán)信息區(qū)的樣式,大家可以做個(gè)參考2016-12-12
JavaScript forEach中return失效問(wèn)題解決方案
這篇文章主要介紹了JavaScript forEach中return失效問(wèn)題解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
JavaScript使用IndexedDB進(jìn)行數(shù)據(jù)存儲(chǔ)
在現(xiàn)代Web應(yīng)用開(kāi)發(fā)中,數(shù)據(jù)存儲(chǔ)是一個(gè)重要的環(huán)節(jié),傳統(tǒng)的cookie和localStorage/sessionStorage雖然簡(jiǎn)單易用,但在存儲(chǔ)容量和功能上存在一定的局限性,IndexedDB作為一種強(qiáng)大的客戶端存儲(chǔ)解決方案,為前端開(kāi)發(fā)者提供了更高級(jí)的數(shù)據(jù)存儲(chǔ)能力2025-05-05

