JS函數(shù)和對象全解析
一、垃圾回收機制
JS作為高級語言,無需開發(fā)者手動分配和釋放內(nèi)存,核心依賴“垃圾回收機制(GC)”自動清理不再使用的內(nèi)存空間,避免內(nèi)存泄漏。
1. 核心原則
垃圾回收的核心是“識別并回收不可達對象”——當一個對象無法通過任何引用鏈訪問到時,就會被標記為“垃圾”,等待GC清理。
2. 兩種常見回收算法
標記-清除算法(主流):這是現(xiàn)代瀏覽器最常用的算法,分兩步執(zhí)行:
- 標記階段:GC從全局對象(如window、global)出發(fā),遍歷所有可訪問的對象并做標記;
- 清除階段:遍歷內(nèi)存中所有對象,清除未被標記的對象,釋放其占用的內(nèi)存。
引用計數(shù)算法(淘汰):通過統(tǒng)計對象被引用的次數(shù)判斷是否回收——引用次數(shù)為0則標記為垃圾。但存在致命缺陷:循環(huán)引用時(A引用B,B引用A,且兩者均無其他引用),引用次數(shù)永遠不為0,導(dǎo)致內(nèi)存泄漏。
3. 實用注意事項
雖然GC自動執(zhí)行,但不良代碼仍可能導(dǎo)致內(nèi)存泄漏,需注意:
- 避免意外全局變量:未聲明的變量會掛載到window上,長期無法回收,建議用let/const替代var,減少全局變量使用;
- 及時清除無用引用:如DOM元素刪除后,需清空對應(yīng)的JS引用(例:elem = null);
- 慎用閉包:閉包會保留外層函數(shù)的變量引用,過度使用可能導(dǎo)致內(nèi)存占用過高(下文詳細說)。
二、閉包
閉包是JS的核心特性,也是面試高頻考點,理解它能輕松實現(xiàn)模塊化、狀態(tài)保存等功能。
1. 定義與本質(zhì)
當一個函數(shù)嵌套另一個函數(shù),且內(nèi)層函數(shù)引用了外層函數(shù)的變量/參數(shù),同時內(nèi)層函數(shù)被外部訪問時,就形成了閉包。本質(zhì)是“內(nèi)層函數(shù)攜帶了外層函數(shù)的作用域上下文”,讓外層變量在函數(shù)執(zhí)行結(jié)束后仍不被回收。
2. 經(jīng)典案例
實現(xiàn)計數(shù)器(保存狀態(tài),避免全局污染)
function createCounter() {
let count = 0; // 外層函數(shù)變量,被內(nèi)層引用
return function() {
count++; // 內(nèi)層函數(shù)訪問外層變量
return count;
};
}
const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3解析:createCounter執(zhí)行后,按常理count會被GC回收,但因內(nèi)層函數(shù)被counter引用,閉包保留了count的引用,使其能持續(xù)累加,且count無法被外部直接修改,實現(xiàn)了“私有變量”的效果。
3. 應(yīng)用場景與坑點
常用場景:
- 模塊化封裝:隱藏內(nèi)部變量,只暴露需要的方法(類似JS模塊的雛形);
- 延遲執(zhí)行:如定時器、事件回調(diào)中訪問外層變量;
- 狀態(tài)緩存:如上述計數(shù)器、防抖節(jié)流中的狀態(tài)保存。
注意坑點:
閉包會延長外層變量的生命周期,過度使用會增加內(nèi)存負擔(dān),甚至導(dǎo)致內(nèi)存泄漏。建議:僅在需要保存狀態(tài)/封裝變量時使用,使用完畢后可通過“清空引用”(如counter = null)釋放內(nèi)存。
三、函數(shù)參數(shù)
JS函數(shù)參數(shù)看似簡單,實則有諸多進階技巧,能大幅提升代碼靈活性,覆蓋默認值、剩余參數(shù)、解構(gòu)傳參等場景。
1. 默認參數(shù)(ES6+)
ES6前需通過邏輯判斷設(shè)置默認值(如param = param || 'default'),但存在缺陷(若參數(shù)為0、false等假值,會被誤判為無參)。ES6新增默認參數(shù)語法,簡潔且精準:
// 基礎(chǔ)用法
function greet(name = 'Guest', age = 18) {
console.log(`Hello ${name}, you are ${age} years old`);
}
greet(); // Hello Guest, you are 18 years old
greet('Tom'); // Hello Tom, you are 18 years old
// 注意:默認參數(shù)需放在參數(shù)列表末尾
function fn(a, b = 2) {} // 合法
function fn(b = 2, a) {} // 不推薦,易混淆2. 剩余參數(shù)(…rest)
當函數(shù)參數(shù)數(shù)量不確定時,用剩余參數(shù)(…+變量名)接收多余參數(shù),返回一個數(shù)組(區(qū)別于arguments的類數(shù)組),便于遍歷操作:
// 求和函數(shù)(支持任意數(shù)量參數(shù))
function sum(...nums) {
return nums.reduce((total, num) => total + num, 0);
}
console.log(sum(1,2,3)); // 6
console.log(sum(4,5,6,7)); // 22
// 剩余參數(shù)與普通參數(shù)結(jié)合(剩余參數(shù)必須在最后)
function fn(a, b, ...rest) {
console.log(a, b); // 1 2
console.log(rest); // [3,4,5]
}3. 參數(shù)解構(gòu)(ES6+)
當參數(shù)為對象/數(shù)組時,可通過解構(gòu)直接提取屬性/元素,簡化代碼:
// 對象解構(gòu)傳參
function getUserInfo({ name, age, gender = 'male' }) {
console.log(`姓名:${name},年齡:${age},性別:${gender}`);
}
getUserInfo({ name: 'Tom', age: 20 }); // 姓名:Tom,年齡:20,性別:male
// 數(shù)組解構(gòu)傳參
function getSum([a, b, c]) {
return a + b + c;
}
console.log(getSum([1,2,3])); // 6四、ES6箭頭函數(shù):簡潔與this的重塑
箭頭函數(shù)是ES6最常用的語法糖,不僅簡化函數(shù)寫法,更重塑了this的指向規(guī)則,解決了傳統(tǒng)函數(shù)this指向混亂的問題。
1. 基礎(chǔ)語法
// 無參數(shù),單語句
const fn1 = () => console.log('Hello');
// 單參數(shù),單語句(可省略括號)
const fn2 = num => num * 2;
// 多參數(shù),多語句(需加括號和大括號,return不可省略)
const fn3 = (a, b) => {
const total = a + b;
return total;
};
// 返回對象(需加小括號,避免大括號被解析為代碼塊)
const fn4 = () => ({ name: 'Tom', age: 20 });2. 核心特性:this指向
傳統(tǒng)函數(shù)(普通函數(shù)、構(gòu)造函數(shù))的this指向“調(diào)用者”,而箭頭函數(shù)沒有自己的this,其this繼承自外層執(zhí)行上下文的this,且一旦綁定無法修改(call、apply、bind也無效)。
// 傳統(tǒng)函數(shù)this指向問題
const obj = {
name: 'Tom',
sayHi: function() {
setTimeout(function() {
console.log(this.name); // undefined(this指向window)
}, 1000);
}
};
// 箭頭函數(shù)解決this問題
const obj2 = {
name: 'Tom',
sayHi: function() {
setTimeout(() => {
console.log(this.name); // Tom(this繼承自sayHi的this,即obj2)
}, 1000);
}
};3. 適用與不適用場景
適用場景:
- 回調(diào)函數(shù)(定時器、數(shù)組方法forEach/map等),避免this指向混亂;
- 簡單的工具函數(shù)(無復(fù)雜this需求),簡化語法。
不適用場景:
- 構(gòu)造函數(shù):箭頭函數(shù)無法作為構(gòu)造函數(shù)(無prototype,不能用new關(guān)鍵字);
- 對象方法:若方法需訪問對象自身的this,建議用普通函數(shù);
- 需要arguments對象的場景:箭頭函數(shù)沒有arguments,需用剩余參數(shù)替代。
到此這篇關(guān)于JS函數(shù)和對象全解析的文章就介紹到這了,更多相關(guān)js函數(shù)和對象內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
ES6新特性二:Iterator(遍歷器)和for-of循環(huán)詳解
這篇文章主要介紹了ES6新特性二:Iterator(遍歷器)和for-of循環(huán),結(jié)合實例形式分析了ES6中Iterator(遍歷器)和for-of循環(huán)遍歷操作的相關(guān)實現(xiàn)技巧與注意事項,需要的朋友可以參考下2017-04-04
javaScript 實現(xiàn)重復(fù)輸出給定的字符串的常用方法小結(jié)
這篇文章主要介紹了javaScript 實現(xiàn)重復(fù)輸出給定的字符串的常用方法,總結(jié)分析了JavaScript重復(fù)輸出給定字符串的4種常見操作技巧,需要的朋友可以參考下2020-02-02

