JavaScript中的作用域與閉包、原型與原型鏈、異步與單線程
一、作用域與閉包
作用域和閉包是JS中的兩個(gè)重要概念,了解其原理可以方便我們更好地理解JS的一些細(xì)節(jié)。作用域描述了程序源代碼在何處可以訪問變量、函數(shù)等標(biāo)識符,而閉包則是指有權(quán)訪問另一個(gè)函數(shù)作用域內(nèi)變量的函數(shù)。
1. 作用域
作用域分為全局作用域和局部作用域。全局作用域是定義在最外層,所有的內(nèi)容代碼都可以訪問它;而局部作用域則是函數(shù)內(nèi)部定義的變量,在函數(shù)執(zhí)行完之后會(huì)被銷毀。
我們可以通過塊作用域和函數(shù)作用域來更好地控制變量的作用域。
//塊作用域 if (true) { let x = 1; } console.log(x); //ReferenceError: x is not defined,x只能在if塊作用域內(nèi)訪問 //函數(shù)作用域 function foo() { let y = 2; } console.log(y); //ReferenceError: y is not defined,y只能在foo函數(shù)作用域內(nèi)訪問
關(guān)于作用域的重要性在于可以避免變量的命名沖突、保護(hù)變量不被誤修改以及提供更好的可維護(hù)性。
2. 閉包
閉包實(shí)際上指的是函數(shù)和聲明該函數(shù)的詞法環(huán)境的組合,即函數(shù)體內(nèi)的引用環(huán)境。在函數(shù)內(nèi)定義的變量以及函數(shù)參數(shù)都是在詞法環(huán)境中聲明的,因此都可以通過閉包被訪問。閉包可以實(shí)現(xiàn)一些高階函數(shù)的功能,比如計(jì)數(shù)器、函數(shù)記憶、數(shù)據(jù)緩存等。
function counter() { var count = 0; function add() { count++; console.log(count); } return add; } var counter1 = counter(); var counter2 = counter(); counter1();// 1 counter1();// 2 counter2();// 1 counter2();// 2
上述代碼實(shí)現(xiàn)了多個(gè)計(jì)數(shù)器的功能,而這正是閉包的作用。
二、原型與原型鏈
原型是JS中許多復(fù)雜特性的基礎(chǔ),構(gòu)成了JS中的面向?qū)ο髾C(jī)制。它是JS中每個(gè)對象都擁有的一個(gè)內(nèi)置的屬性,通過該屬性可實(shí)現(xiàn)屬性繼承以及方法的共享。
1. 原型
在JS中,每個(gè)對象都有一個(gè)內(nèi)部的[[prototype]]屬性,也稱為原型,指向他的原型對象。通過原型,對象可以繼承原型對象的屬性和方法。
let emptyObj = {}; console.log(emptyObj.__proto__); //Object.prototype
在JS中,每個(gè)對象都是由構(gòu)造函數(shù)創(chuàng)建的。程序可以自定義構(gòu)造函數(shù),以此來創(chuàng)建自己的對象。如果在構(gòu)造函數(shù)中指定了一個(gè)prototype對象,那么所有的實(shí)例都會(huì)繼承該prototype對象的屬性和方法。
function Person(name) { this.name = name; } Person.prototype.sayHi = function () { console.log(`Hi, my name is ${this.name}`); }; let person1 = new Person('張三'); person1.sayHi(); //Hi, my name is 張三 let person2 = new Person('李四'); person2.sayHi(); //Hi, my name is 李四
2. 原型鏈
原型鏈?zhǔn)菍?shí)現(xiàn)JS中繼承的基礎(chǔ)。對象的原型可能是其他對象,而這些對象同樣具有原型。這些關(guān)系被稱為原型鏈。如果一個(gè)對象在它的原型鏈上找不到特定的屬性或者方法,那么它會(huì)繼續(xù)查找它的原型鏈。在找到匹配的方法或?qū)傩灾?,?huì)沿著原型鏈逐級查找。
let emptyObj = {}; console.log(emptyObj.toString()); //[object Object],toString方法被Object.prototype繼承 console.log(emptyObj.__proto__); //Object.prototype console.log(emptyObj.__proto__.__proto__); //null,原型鏈到達(dá)了Object.prototype的上層
原型鏈?zhǔn)荍S中非常重要的概念,對了解繼承、原型、對象、構(gòu)造函數(shù)等都具有很大的幫助。
三、異步與單線程
JS是單線程的語言,也就是說JS引擎中只有一個(gè)線程在執(zhí)行任務(wù)。如果任務(wù)比較耗時(shí),會(huì)導(dǎo)致線程阻塞,即后續(xù)任務(wù)無法執(zhí)行。
1. 異步
為了解決單線程帶來的問題,JS引入了異步編程的方式。JS中的異步函數(shù)通常是由回調(diào)函數(shù)、Promise、Generator、async/await等方式實(shí)現(xiàn)。
回調(diào)函數(shù)
回調(diào)函數(shù)是最常見的異步實(shí)現(xiàn)方式,當(dāng)異步操作完成時(shí),將調(diào)用一個(gè)函數(shù),以通知應(yīng)用程序。
function loadData(callback) { setTimeout(() => { callback('This is the data'); }, 2000); } function loadDataCallback(data) { console.log(data); } loadData(loadDataCallback); //2秒后輸出This is the data
Promise
Promise是ES6引入的一個(gè)新特性,它是一種更加優(yōu)雅的異步實(shí)現(xiàn)方式。Promise支持鏈?zhǔn)秸{(diào)用、錯(cuò)誤捕獲等功能。
function loadData() { return new Promise((resolve, reject) => { setTimeout(() => { resolve('This is the data'); }, 2000); }); } loadData().then((data) => { console.log(data); });
2. 事件循環(huán)
JS采用事件循環(huán)機(jī)制,它會(huì)不斷地檢查任務(wù)隊(duì)列,如果隊(duì)列中有任務(wù),就將任務(wù)取出來執(zhí)行。
事件循環(huán)提供了異步編程的基礎(chǔ),多個(gè)異步任務(wù)可以并行執(zhí)行,并且不會(huì)發(fā)生阻塞,這使得JS具有高并發(fā)性能。
console.log('start'); setTimeout(() => { console.log('2s later'); }, 2000); console.log('end'); //輸出start,end //2s后輸出2s later
學(xué)會(huì)異步編程,是JS開發(fā)中非常重要的一部分。
四、總結(jié)
JavaScript的三座大山指的是:作用域和閉包、原型和原型鏈、異步與單線程,這些概念在日常的開發(fā)工作中經(jīng)常被提及,并對我們理解和編寫高質(zhì)量的JavaScript代碼至關(guān)重要。到此這篇關(guān)于JavaScript中的作用域與閉包、原型與原型鏈、異步與單線程的文章就介紹到這了,更多相關(guān)JavaScript的三座大山內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
原生JS封裝拖動(dòng)驗(yàn)證滑塊的實(shí)現(xiàn)代碼示例
這篇文章主要介紹了原生JS封裝拖動(dòng)驗(yàn)證滑塊的實(shí)現(xiàn)代碼示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06electron實(shí)現(xiàn)讀取和寫入配置文件的示例詳解
這篇文章主要介紹了electron實(shí)現(xiàn)讀取和寫入配置文件的示例,文中通過代碼示例和圖文結(jié)合的方式介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-03-03js實(shí)現(xiàn)簡易計(jì)數(shù)器功能
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)計(jì)數(shù)器功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08JavaScript點(diǎn)擊按鈕后彈出透明浮動(dòng)層的方法
這篇文章主要介紹了JavaScript點(diǎn)擊按鈕后彈出透明浮動(dòng)層的方法,可實(shí)現(xiàn)點(diǎn)擊按鈕彈出居中的透明浮動(dòng)層的效果,涉及javascript操作鼠標(biāo)事件及頁面樣式的相關(guān)技巧,需要的朋友可以參考下2015-05-05javascript之學(xué)會(huì)吝嗇 精簡代碼
前端開發(fā),要學(xué)會(huì)吝嗇:2010-04-04