JavaScript中的作用域與閉包、原型與原型鏈、異步與單線程
一、作用域與閉包
作用域和閉包是JS中的兩個重要概念,了解其原理可以方便我們更好地理解JS的一些細(xì)節(jié)。作用域描述了程序源代碼在何處可以訪問變量、函數(shù)等標(biāo)識符,而閉包則是指有權(quán)訪問另一個函數(shù)作用域內(nèi)變量的函數(shù)。
1. 作用域
作用域分為全局作用域和局部作用域。全局作用域是定義在最外層,所有的內(nèi)容代碼都可以訪問它;而局部作用域則是函數(shù)內(nèi)部定義的變量,在函數(shù)執(zhí)行完之后會被銷毀。
我們可以通過塊作用域和函數(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ù)的功能,比如計數(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)了多個計數(shù)器的功能,而這正是閉包的作用。
二、原型與原型鏈
原型是JS中許多復(fù)雜特性的基礎(chǔ),構(gòu)成了JS中的面向?qū)ο髾C(jī)制。它是JS中每個對象都擁有的一個內(nèi)置的屬性,通過該屬性可實(shí)現(xiàn)屬性繼承以及方法的共享。
1. 原型
在JS中,每個對象都有一個內(nèi)部的[[prototype]]屬性,也稱為原型,指向他的原型對象。通過原型,對象可以繼承原型對象的屬性和方法。
let emptyObj = {}; console.log(emptyObj.__proto__); //Object.prototype
在JS中,每個對象都是由構(gòu)造函數(shù)創(chuàng)建的。程序可以自定義構(gòu)造函數(shù),以此來創(chuàng)建自己的對象。如果在構(gòu)造函數(shù)中指定了一個prototype對象,那么所有的實(shí)例都會繼承該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)系被稱為原型鏈。如果一個對象在它的原型鏈上找不到特定的屬性或者方法,那么它會繼續(xù)查找它的原型鏈。在找到匹配的方法或?qū)傩灾埃瑫刂玩溨鸺壊檎摇?/p>
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引擎中只有一個線程在執(zhí)行任務(wù)。如果任務(wù)比較耗時,會導(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)異步操作完成時,將調(diào)用一個函數(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引入的一個新特性,它是一種更加優(yōu)雅的異步實(shí)現(xiàn)方式。Promise支持鏈?zhǔn)秸{(diào)用、錯誤捕獲等功能。
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ī)制,它會不斷地檢查任務(wù)隊(duì)列,如果隊(duì)列中有任務(wù),就將任務(wù)取出來執(zhí)行。
事件循環(huán)提供了異步編程的基礎(chǔ),多個異步任務(wù)可以并行執(zhí)行,并且不會發(fā)生阻塞,這使得JS具有高并發(fā)性能。
console.log('start'); setTimeout(() => { console.log('2s later'); }, 2000); console.log('end'); //輸出start,end //2s后輸出2s later
學(xué)會異步編程,是JS開發(fā)中非常重要的一部分。
四、總結(jié)
JavaScript的三座大山指的是:作用域和閉包、原型和原型鏈、異步與單線程,這些概念在日常的開發(fā)工作中經(jīng)常被提及,并對我們理解和編寫高質(zhì)量的JavaScript代碼至關(guān)重要。到此這篇關(guān)于JavaScript中的作用域與閉包、原型與原型鏈、異步與單線程的文章就介紹到這了,更多相關(guān)JavaScript的三座大山內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
element?UI中在?el-select?與?el-tree?結(jié)合組件實(shí)現(xiàn)過程
項(xiàng)目上實(shí)現(xiàn)某個功能,使用到了?el-select?和?el-tree?組合實(shí)現(xiàn),記錄下兩者結(jié)合的實(shí)現(xiàn)過程,對?el-select?與?el-tree?結(jié)合組件實(shí)現(xiàn)過程感興趣的朋友跟隨小編一起看看吧2023-02-02javascript字符串替換函數(shù)如何一次性全部替換掉
這篇文章主要介紹了JS字符串替換函數(shù)replace如何一次性全部替換的相關(guān)資料,需要的朋友可以參考下2015-10-10阻止JavaScript事件冒泡傳遞(cancelBubble 、stopPropagation)
阻止JavaScript事件冒泡傳遞(cancelBubble 、stopPropagation)...2007-05-05基于JavaScript實(shí)現(xiàn)高德地圖和百度地圖提取行政區(qū)邊界經(jīng)緯度坐標(biāo)
本文給大家介紹javascript實(shí)現(xiàn)高德地圖和百度地圖提取行政區(qū)邊界經(jīng)緯度坐標(biāo)的相關(guān)知識,本文實(shí)用性非常高,代碼簡單易懂,需要的朋友參考下吧2016-01-01微信小程序中this.data與this.setData的區(qū)別詳解
這篇文章主要給大家介紹了關(guān)于微信小程序中this.data與this.setData區(qū)別的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧2018-09-09JS組件系列之Bootstrap table表格組件神器【二、父子表和行列調(diào)序】
本文結(jié)合Bootstrap table的父子表和行列調(diào)序的用法再來介紹下它稍微高級點(diǎn)的用法。對bootstrap表格組件相關(guān)知識感興趣的朋友一起學(xué)習(xí)吧2016-05-05《javascript設(shè)計模式》學(xué)習(xí)筆記七:Javascript面向?qū)ο蟪绦蛟O(shè)計組合模式詳解
這篇文章主要介紹了Javascript面向?qū)ο蟪绦蛟O(shè)計組合模式,結(jié)合實(shí)例形式分析了《javascript設(shè)計模式》中Javascript面向?qū)ο蠼M合模式相關(guān)概念、原理、定義、用法及操作注意事項(xiàng),需要的朋友可以參考下2020-04-04微信 jssdk 簽名錯誤invalid signature的解決方法
這篇文章主要介紹了微信 jssdk 簽名錯誤invalid signature的解決方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-01-01