最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

通過JS運(yùn)行機(jī)制的角度說說作用域

 更新時(shí)間:2019年03月12日 10:01:00   作者:不思  
這篇文章主要給大家介紹了如何通過JS運(yùn)行機(jī)制的角度說說作用域的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者使用JS作用域具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧

前言

任何程序設(shè)計(jì)語言都有作用域的概念,簡單的說,作用域就是變量與函數(shù)的可訪問范圍。JS中的作用域、閉包、this機(jī)制和原型往往是最難理解的概念之一。筆者將通過幾篇文章和大家談?wù)勛约旱睦斫猓M麑?duì)大家的學(xué)習(xí)有一些幫助。如果有什么理解偏差的地方,希望大家可以評(píng)論指出,相互學(xué)習(xí)。

有過一定編程經(jīng)驗(yàn)的同學(xué),一定不會(huì)對(duì)作用域感到陌生,在C/C++/Java中等語言中,作用域從來沒有JavaScript中的作用域那樣令人困惑以致于成為一個(gè)大多數(shù)JS開發(fā)者都難以跨過的門檻。

作用域形成機(jī)制

JS中存在的三種作用域類型:全局作用域,函數(shù)作用域和ES6中新加入的塊級(jí)作用域。

var a = 1;

function foo() {
 var b = 2;
 console.log(a);		// 1
 console.log(b);		// 2
 console.log(c);		// ReferenceError
}

function foo1() {
 var c = 3;
 console.log(a);		// 1
 console.log(b);		// ReferenceError
 console.log(c);		// 3
}

console.log(a);			// 1
console.log(b); 		// ReferenceError
console.log(c);			// ReferenceError
foo();
foo1();

從上面的例子可以看到,每個(gè)函數(shù)內(nèi)部形成了屬于自己的作用域,函數(shù)內(nèi)部聲明的變量僅僅在定義的函數(shù)內(nèi)部才可以訪問。全局作用域中可以訪問到的有a,foo,foo作用域中可以訪問到的有b,foo,a,foo1的作用域中可以訪問到的有c,foo,a。因?yàn)閒oo的作用域嵌套在全局作用域之中,當(dāng)console.log(a);執(zhí)行的時(shí)候,JS在foo的作用域查找不到a,就會(huì)到它的上層(這里是foo的上層直接就是全局作用域)查找,發(fā)現(xiàn)這里聲明了一個(gè)a,將它的值打印了出來。這種從里到外的查找就是根據(jù)作用域鏈查找。foo1和foo的作用域沒有嵌套關(guān)系,所以相互隔離。

如果函數(shù)中使用了未聲明的變量怎么辦?

function foo() {
	a = 2;
}

foo();
console.log(a);		// 2

JS引擎在foo中查找不到a的聲明,便會(huì)到它的上層(這里是全局作用域中)查找,這個(gè)時(shí)候還是沒有查找到a的聲明,在非嚴(yán)格模式下,JS引擎會(huì)在全局中自動(dòng)聲明一個(gè)a,這個(gè)時(shí)候,未經(jīng)聲明的變量a實(shí)際上泄漏到了全局作用域中。

只有使用未聲明的變量才會(huì)出現(xiàn)變量泄漏的問題么,其實(shí),不僅僅這種寫法會(huì)出現(xiàn),更常見的也會(huì)出現(xiàn)在for循環(huán)和if代碼塊中也會(huì)出現(xiàn)。

for(var i=1;i<10;i++) {
 console.log(i);
}

console.log(i);		// 10,	這里的i泄漏到了全局作用域中

if(true) {
 var a = 2;
}

console.log(a);		// 2, 這里的a也泄漏到了全局變量之中

如果你學(xué)習(xí)過C語言系列的語法,往往很容易感到困惑,if和for居然沒有作用域,這真是太奇怪了。這一切的問題的根源,都是由于ES6之前沒有塊級(jí)作用域?qū)е碌?。所以可想而知,if包裹的代碼塊,同樣里面的聲明也是暴露出來的~

一切問題的解決直到ES6中引入了let和const得以完美的解決。使用let和const,將可以使用塊級(jí)作用域,使得聲明變量泄漏的問題得以解決。

for(let i=1;i<10;i++) {
 console.log(i);
}

console.log(i);		// ReferenceError

if(true) {
 let a = 2;
}

console.log(a);		// ReferenceError

聲明提升機(jī)制

對(duì)于在JS中聲明的不論是變量還是函數(shù),基本上都會(huì)存在著變量聲明提升的行為,將變量的聲明提升到所在作用域的頂端。ES6中的let和const不會(huì),在未聲明之前都不可以使用。

看看下面的代碼

console.log(a);				// undefined
console.log(b);				// undefined
console.log(foo);			// Function
console.log(foo2);		// ReferenceError

function foo () {
 console.log('聲明提升了哈');
}

var a = 1;

var b = function foo2() {
 console.log('不同的函數(shù)聲明方式提升的結(jié)果也不一樣哦');
};

JS 引擎解釋這段代碼之前首先對(duì)代碼中所有的變量進(jìn)行了聲明的提升,函數(shù)聲明的提升的優(yōu)先級(jí)是高于普通變量的,函數(shù)聲明會(huì)整個(gè)提升到所在作用域的頂端(但是以函數(shù)表達(dá)式方式聲明的函數(shù)不會(huì)),代碼實(shí)際上是下面這個(gè)樣子:

function foo () {
 console.log('聲明提升了哈');
}
var a;
var b;
var foo2;

console.log(a);
console.log(b);
console.log(foo);
console.log(foo2);

b = function foo2 () {
 console.log('不同的函數(shù)聲明方式提升的結(jié)果也不一樣哦');
}

靜態(tài)作用域機(jī)制(詞法作用域)

關(guān)于JS中的作用域,需要明確的一點(diǎn)就是,JS中只存在靜態(tài)作用域(詞法作用域)。靜態(tài)作用域是什么意思呢?意思就是它的作用域在你寫下代碼的時(shí)候就已經(jīng)確定了,和函數(shù)的調(diào)用順序無關(guān),了解這一點(diǎn)。就可以對(duì)一些常見的現(xiàn)象進(jìn)行解釋。

var a = 2;
function foo() {
 console.log(a);
}

var obj = {
 a: 3,
 foo: foo
}

obj.foo();		// 2

foo中的a在代碼寫完時(shí)就確認(rèn)了,指向了全局作用域中的a,一旦確定就無法更改了。同理,下面的代碼

function foo() {
 console.log(b);			// ReferenceError
}

function foo1 () {
 var b = 1;
 foo();
}

foo1();

這里,JS引擎在全局作用域中查找不到b,所以會(huì)拋出一個(gè)異常。所以可以明確的道理是,foo的作用域和foo1的作用域仍然是相互獨(dú)立的,不會(huì)因?yàn)檎{(diào)用時(shí)候的順序而更改作用域的嵌套順序,靜態(tài)作用域在代碼書寫時(shí)就已經(jīng)確定無法更改了,明白這一點(diǎn)在分析JS代碼的時(shí)候尤為重要。

坑外話

變量的遮蔽效應(yīng)

在函數(shù)中定義的變量會(huì)遮蔽上層作用域中同名的變量,兩個(gè)變量互不影響。

var a = 1;
function foo() {
 var a = 2;
 console.log(a);	// 2
}
console.log(a);		// 1

Try-Catch 中的塊級(jí)作用域

try-catch的catch中會(huì)創(chuàng)建一個(gè)塊級(jí)作用域,該作用域內(nèi)變量的表現(xiàn)同樣遵守變量的聲明提升規(guī)則。

try {
 throw undefined;
}catch(e) {
 a = 1;
 console.log(e);		// undefined
}

console.log(a);			// 1,	變量提升規(guī)則
console.log(e);			// ReferenceError,catch的塊作用域中定義的變量

隱式聲明

以參數(shù)形式傳入的變量在函數(shù)內(nèi)部實(shí)際上存在的隱式的聲明,使用時(shí)不算作未聲明的變量。

function foo(a) {
 a = 1;
 console.log(a);
}

foo();						// 1
console.log(a);		// ReferenceError

本來想一篇文章寫完作用域和閉包的,想例子實(shí)在是累,就拆作兩篇吧,逃~

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • JavaScript兩種axios取消請(qǐng)求方式小結(jié)

    JavaScript兩種axios取消請(qǐng)求方式小結(jié)

    本文主要介紹了JavaScript兩種axios取消請(qǐng)求方式小結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • JS中靜態(tài)頁面實(shí)現(xiàn)微信分享功能

    JS中靜態(tài)頁面實(shí)現(xiàn)微信分享功能

    小編使用ajax實(shí)現(xiàn)靜態(tài)頁面也能實(shí)現(xiàn)微信分享功能,今天小編給大家分享實(shí)現(xiàn)代碼,對(duì)js靜態(tài)頁面微信分享功能感興趣的朋友參考下本文
    2017-02-02
  • JS 日期比較大小的簡單實(shí)例

    JS 日期比較大小的簡單實(shí)例

    本篇文章主要是對(duì)JS日期比較大小的簡單實(shí)例進(jìn)行了介紹,需要的朋友可以過來參考下,希望對(duì)大家有所幫助
    2014-01-01
  • 實(shí)例學(xué)習(xí)JavaScript讀取和寫入cookie

    實(shí)例學(xué)習(xí)JavaScript讀取和寫入cookie

    本篇內(nèi)容主要給大家通過實(shí)例講述了JavaScript讀取和寫入cookie的相關(guān)知識(shí)點(diǎn),有這方面需要的朋友參考下吧。
    2018-01-01
  • 詳解webpack 配合babel 將es6轉(zhuǎn)成es5 超簡單實(shí)例

    詳解webpack 配合babel 將es6轉(zhuǎn)成es5 超簡單實(shí)例

    本篇文章主要介紹了詳解webpack 配合babel 將es6轉(zhuǎn)成es5 超簡單實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • 前端實(shí)現(xiàn)文本溢出展開和收起功能

    前端實(shí)現(xiàn)文本溢出展開和收起功能

    在現(xiàn)代網(wǎng)頁設(shè)計(jì)中,文本是網(wǎng)頁中最重要的內(nèi)容之一,然而,當(dāng)文本超出其容器的大小時(shí),會(huì)發(fā)生文本溢出的問題,文本溢出不僅會(huì)影響網(wǎng)頁的視覺效果,還會(huì)影響網(wǎng)頁的可讀性和可用性,所以本文給大家介紹了前端實(shí)現(xiàn)文本溢出展開和收起功能的方法,需要的朋友可以參考下
    2025-04-04
  • 微信小程序點(diǎn)擊view動(dòng)態(tài)添加樣式過程解析

    微信小程序點(diǎn)擊view動(dòng)態(tài)添加樣式過程解析

    這篇文章主要介紹了微信小程序點(diǎn)擊view動(dòng)態(tài)添加樣式過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • JavaScript console的使用方法實(shí)例分析

    JavaScript console的使用方法實(shí)例分析

    這篇文章主要介紹了JavaScript console的使用方法,結(jié)合實(shí)例形式分析了JavaScript console的使用方法與操作注意事項(xiàng),需要的朋友可以參考下
    2020-04-04
  • 等待指定時(shí)間后自動(dòng)跳轉(zhuǎn)或關(guān)閉當(dāng)前頁面的js代碼

    等待指定時(shí)間后自動(dòng)跳轉(zhuǎn)或關(guān)閉當(dāng)前頁面的js代碼

    本文為大家詳細(xì)介紹下如何通過js實(shí)現(xiàn)等待指定時(shí)間后自動(dòng)跳轉(zhuǎn)或關(guān)閉當(dāng)前頁面的腳步代碼,感興趣的朋友可以參考下哈,希望對(duì)大家有所幫助
    2013-07-07
  • JS實(shí)現(xiàn)圖片橫向滾動(dòng)效果示例代碼

    JS實(shí)現(xiàn)圖片橫向滾動(dòng)效果示例代碼

    圖片橫向滾動(dòng)效果,大家可能都已經(jīng)很熟悉了,本文為大家介紹下使用js實(shí)現(xiàn)橫向滾動(dòng)效果,喜歡的朋友可以參考下,希望對(duì)大家有所幫助
    2013-09-09

最新評(píng)論

云龙县| 美姑县| 罗田县| 平陆县| 荥阳市| 洞口县| 武汉市| 达拉特旗| 大厂| 博湖县| 娄底市| 神池县| 丰宁| 荥阳市| 皮山县| 兴文县| 石狮市| 玛纳斯县| 乌恰县| 红桥区| 布拖县| 通城县| 海口市| 峨山| 鸡东县| 宜都市| 佛山市| 武汉市| 扎囊县| 正宁县| 林西县| 微博| 闻喜县| 东乡| 朔州市| 无为县| 鸡东县| 于田县| 民乐县| 保靖县| 庆云县|