亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

深入理解javascript作用域,作用域鏈,閉包的面試題

  發(fā)布時(shí)間:2020-02-21 15:16:34   作者:weixin_30535043   我要評(píng)論
這篇文章主要介紹了javascript作用域,作用域鏈,閉包的面試題,在一些前端面試中經(jīng)常會(huì)問(wèn)題,今天小編特此整理分享到腳本之家平臺(tái),需要的朋友可以參考下

一、概要

作用域和作用域鏈?zhǔn)莏s中非常重要的特性,關(guān)系到理解整個(gè)js體系,閉包是對(duì)作用域的延伸,其他語(yǔ)言也有閉包的特性。

那什么是作用域?作用域指的是一個(gè)變量和函數(shù)的作用范圍。

1、js中函數(shù)內(nèi)聲明的所有變量在函數(shù)體內(nèi)始終是可見(jiàn)的;

2、在ES6中有全局作用域和局部作用域,但是沒(méi)有沒(méi)有塊級(jí)作用域(catch只在其內(nèi)部生效);

3、局部變量的優(yōu)先級(jí)高于全局變量。

文章首發(fā):https://www.mwcxs.top/page/574.html

二、作用域

我們來(lái)舉幾個(gè)栗子:

2.1變量提升

var scope="global";
function scopeTest(){
    console.log(scope);
    var scope="local"  
}
scopeTest(); //undefined

上面的代碼輸出是undefined,這是因?yàn)榫植孔兞?code>scope變量提升了,等效于下面

var scope="global";
function scopeTest(){
    var scope;
    console.log(scope);
    scope="local"  
}
scopeTest(); //undefined

注意,如果在局部作用域中忘記var,那么變量就被聲明為全局變量。

var scope="global";
function scopeTest(){
    console.log(scope);
    scope="local"  
}
scopeTest(); //global
var scope="global";
function scopeTest(){
    scope="local" 
    console.log(scope);
}
scopeTest(); //local

2.2沒(méi)有塊級(jí)作用域

和我們其他常用語(yǔ)言不同的是,js中沒(méi)有塊級(jí)作用域

var data = [];
for (var i = 0; i < 3; i++) {
  data[i] = function () {
    console.log(i);
  };
}
data[0]();	// 3
data[1]();	// 3
data[2]();	// 3

2.3作用域鏈

每個(gè)函數(shù)都有自己的執(zhí)行上下文環(huán)境,當(dāng)代碼在這個(gè)環(huán)境中執(zhí)行時(shí)候,會(huì)創(chuàng)建變量對(duì)象的作用域鏈,

那什么是作用域鏈?作用域鏈?zhǔn)绞且粋€(gè)對(duì)象列表。

作用域鏈的作用?他保證了變量對(duì)象的有序訪問(wèn)。

作用域鏈開(kāi)始的地方:當(dāng)前代碼執(zhí)行環(huán)境的變量對(duì)象,常被稱之為“活躍對(duì)象”(AO),變量的查找會(huì)從第一個(gè)鏈的對(duì)象開(kāi)始,如果對(duì)象中包含變量屬性,那么就停止查找,如果沒(méi)有就會(huì)繼續(xù)向上級(jí)作用域查找,直到找到全局對(duì)象中,如果找不到就會(huì)報(bào)ReferenceError。

2.4閉包

function createClosure(){
    var name = "jack";
    return {
        setStr:function(){
            name = "rose";
        },
        getStr:function(){
            return name + ":hello";
        }
    }
}
var builder = new createClosure();
builder.setStr();
console.log(builder.getStr()); //rose:hello

上面在函數(shù)中反悔了兩個(gè)閉包,這兩個(gè)閉包都維持著對(duì)外部作用域的引用,因此不管在哪調(diào)用都是能夠訪問(wèn)外部函數(shù)中的變量。在一個(gè)函數(shù)內(nèi)部定義的函數(shù),閉包中會(huì)將外部函數(shù)的自由對(duì)象添加到自己的作用域中,所以可以通過(guò)內(nèi)部函數(shù)訪問(wèn)外部函數(shù)的屬性,這就是js模擬私有變量的一種方式。

注意:由于閉包會(huì)額外的附帶函數(shù)的作用域(內(nèi)部匿名函數(shù)攜帶外部函數(shù)的作用域),因此,閉包會(huì)比其他函數(shù)多占用些內(nèi)存空間,過(guò)度使用會(huì)導(dǎo)致內(nèi)存占用增加。

三、閉包面試題解

由于作用域鏈機(jī)制的影響,閉包只能取得內(nèi)部函數(shù)的最后一個(gè)值,這引起了一個(gè)副作用,如果內(nèi)部函數(shù)在一個(gè)循環(huán)中,那么變量的值始終為最后一個(gè)值。

var data = [];
 
for (var i = 0; i < 3; i++) {
  data[i] = function () {
    console.log(i);
  };
}
data[0]();	// 3
data[1]();	// 3
data[2]();	// 3

如果想強(qiáng)制返回逾期結(jié)果,怎么整?

方法一:立即執(zhí)行函數(shù)

for (var i = 0; i < 3; i++) {
    (function(num) {
        setTimeout(function() {
            console.log(num);
        }, 1000);
    })(i);
}
// 0
// 1
// 2

方法二:返回一個(gè)匿名函數(shù)賦值

var data = [];
for (var i = 0; i < 3; i++) {
  data[i] = (function (num) {
      return function(){
          console.log(num);
      }
  })(i);
}
data[0]();	// 0
data[1]();	// 1
data[2]();	// 2

無(wú)論上是立即執(zhí)行函數(shù)還是返回一個(gè)匿名函數(shù)賦值,原理上都是因?yàn)樽兞康陌粗祩鬟f,所以會(huì)將變量i的值賦值給實(shí)參num,在匿名函數(shù)的內(nèi)部又創(chuàng)建了一個(gè)用于訪問(wèn)num的匿名函數(shù),這樣每一個(gè)函數(shù)都有一個(gè)num的副本,互不影響。

方法三:使用es6的let

var data = [];
for (let i = 0; i < 3; i++) {
  data[i] = function () {
    console.log(i);
  };
}
data[0]();
data[1]();
data[2]();

解釋一下原理:

var data = [];// 創(chuàng)建一個(gè)數(shù)組data;
 
// 進(jìn)入第一次循環(huán)
{ 
	let i = 0; // 注意:因?yàn)槭褂胠et使得for循環(huán)為塊級(jí)作用域
	           // 此次 let i = 0 在這個(gè)塊級(jí)作用域中,而不是在全局環(huán)境中
    data[0] = function() {
    	console.log(i);
	};
}

循環(huán)時(shí),let聲明了i,所以整個(gè)塊是塊級(jí)作用域,那么data[0]這個(gè)函數(shù)就成了一個(gè)閉包,這里用{}表述,只是希望通過(guò)它來(lái)說(shuō)明let存在的時(shí)候,這個(gè)for循環(huán)塊是塊級(jí)作用域,而不是全局作用域。

上面的塊級(jí)作用域,就像函數(shù)作用域一樣,寒暑表執(zhí)行完畢,其中的變量會(huì)被銷毀,但是因?yàn)檫@個(gè)代碼塊中存在一個(gè)閉包,閉包的作用域鏈中引用著塊級(jí)作用域,所以在閉包被調(diào)用之前,這個(gè)塊級(jí)作用域內(nèi)部的變量不會(huì)被銷毀。

// 進(jìn)入第二次循環(huán)
{ 
	let i = 1; // 因?yàn)?let i = 1 和上面的 let i = 0     
	           // 在不同的作用域中,所以不會(huì)相互影響
	data[1] = function(){
         console.log(i);
	}; 
}

當(dāng)執(zhí)行data[1]()時(shí),進(jìn)入下面的執(zhí)行環(huán)境。

{ 
     let i = 1; 
     data[1] = function(){
          console.log(i);
     }; 
}

在上面這個(gè)執(zhí)行環(huán)境中,它會(huì)首先尋找該執(zhí)行環(huán)境中是否存在i,沒(méi)有找到,就沿著作用域鏈繼續(xù)向上找,在其所在的塊級(jí)作用域執(zhí)行環(huán)境中,找到i=1,于是輸出1。

四、思考題

代碼1:

var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){
        return scope;
    }
    return f;
}
checkscope()();    //local scope

代碼2:

var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){
        return scope;
    }
    return f;
}
var foo = checkscope(); 
foo();    //local scope

四、參考

1、https://segmentfault.com/a/1190000000618597

2、https://www.cnblogs.com/zhuzhenwei918/p/6131345.html

總結(jié)

以上就是深入理解javascript作用域,作用域鏈,閉包的面試題的詳細(xì)內(nèi)容,更多關(guān)于js 作用域,作用域鏈,閉包的面試題請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 新手怎么學(xué)JS?JavaScript基礎(chǔ)語(yǔ)法入門要學(xué)什么?

    這篇文章主要介紹了新手怎么學(xué)JS?JavaScript基礎(chǔ)語(yǔ)法入門要學(xué)什么?本文給大家介紹一個(gè)大致的學(xué)習(xí)路線和方向,需要的朋友趕緊一起來(lái)看看吧
    2020-03-19
  • 2020年12道高頻JavaScript手寫面試題及答案

    這篇文章主要介紹了2020年12道高頻JavaScript手寫面試題及答案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編
    2020-01-06
  • JavaScript關(guān)于數(shù)組的四道面試題

    這篇文章主要介紹了JavaScript關(guān)于數(shù)組的四道面試題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)
    2019-12-23
  • 11道JS選擇題(聽(tīng)說(shuō)第一題就難倒80%的人)

    這篇文章主要介紹了11道JS選擇題(聽(tīng)說(shuō)第一題就難倒80%的人),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-12-18
  • 10個(gè)比較流行的JavaScript面試題

    JS 初學(xué)者總是對(duì)this關(guān)鍵字感到困惑,因?yàn)榕c其他現(xiàn)代編程語(yǔ)言相比,JS 中的這this關(guān)鍵字有點(diǎn)棘手。今天小編給大家?guī)?lái)10個(gè)比較流行的JavaScript面試題 ,感興趣的朋友一起
    2019-07-12
  • 10個(gè)JavaScript筆試題解析

    這篇文章主要介紹了10個(gè)JavaScript筆試題解析,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2020-06-02

最新評(píng)論