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

