成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

JavaScript面向?qū)ο髜 作用域和閉包

WilsonLiu95 / 1124人閱讀

摘要:大名鼎鼎的作用域和閉包,面試經(jīng)常會問到。聲明理解閉包,先理解函數(shù)的執(zhí)行過程。閉包的基本結(jié)構(gòu)因為閉包不允許外界直接訪問,所以只能間接訪問函數(shù)內(nèi)部的數(shù)據(jù),獲得函數(shù)內(nèi)部數(shù)據(jù)的使用權(quán)。

大名鼎鼎的作用域和閉包,面試經(jīng)常會問到。閉包(closure)是Javascript語言的一個難點,也是它的特色。

聲明

理解閉包,先理解函數(shù)的執(zhí)行過程。

代碼在執(zhí)行的過程中會有一個預(yù)解析的過程,也就是在代碼的執(zhí)行過程中,會先將代碼讀取到內(nèi)存中,檢查其是否有錯誤,然后將所有聲明在此進行標(biāo)記,讓js解析器知道有這樣的一個名字,后面使用時便不會出現(xiàn)未定義的錯誤,這個標(biāo)記的過程就是提升。

變量的聲明
var num;沒有與之對應(yīng)的數(shù)據(jù),僅僅是讓js解析器知道,你定義了一個num的變量。

函數(shù)的聲明
function foo(){};一個獨立的結(jié)構(gòu),沒有任何語句。首先是將函數(shù)名進行提升,讓js解析器知道有一個foo函數(shù),接著是將函數(shù)名與函數(shù)體連接起來,注意這里并不執(zhí)行函數(shù)體。

代碼演示:

var num = 10;
function foo(){
  console.log(num);
}
foo();

預(yù)解析的過程(變量提升,函數(shù)提升):

var num;
function foo(){
  console.log(num)
}
num = 10;
foo();

代碼執(zhí)行時,首先會執(zhí)行 num = 10; 然后執(zhí)行foo(),進行函數(shù)體,打印出num的值。此時的num訪問到的是全局中定義的num,所以num的值為10.

作用域

以上代碼涉及到作用域的問題,所謂的域,表示的是范圍,所以作用域表示的是作用范圍,也就是一個名字在什么地方可以使用,在什么地方不可使用。

1、詞法作用域

在js中,采用的是詞法作用域,詞法作用域是指在編寫代碼的過程中體現(xiàn)出來的作用范圍,一旦代碼寫好了,不用執(zhí)行,作用范圍就確定好了。

Javascript的作用域無非就是兩種:全局變量和局部變量。

2、詞法作用域的規(guī)則

函數(shù)允許訪問函數(shù)外的數(shù)據(jù)

整個代碼結(jié)構(gòu)中只有函數(shù)可限定作用域

作用域規(guī)則首先使用提升規(guī)則分析

若當(dāng)前作用域中有名字了,就不考慮外面的名字

3、作用域鏈

只有函數(shù)可以構(gòu)成作用域結(jié)構(gòu)。只要存在代碼,就至少有一個作用域,即全局作用域。凡是代碼有函數(shù),那么這個函數(shù)就構(gòu)成一個作用域,如果函數(shù)中還有函數(shù),那么在這個作用域中就又誕生一個作用域,那么將這樣的所有作用域列出來,就可以有一個:函數(shù)內(nèi)指向函數(shù)外的鏈?zhǔn)浇Y(jié)構(gòu)。

作用域鏈變量訪問規(guī)則:看變量在當(dāng)前作用域中,是否有變量的定義與賦值,如果有,則直接使用;如果沒有,則到外面的作用域中查看,如果有,則停止查找,使用外面一層作用域中定義的變量或值,如果沒有,則繼續(xù)往外查找,直到最外層的全局,如果全局也沒有定義,則會報錯: xx is not defined。

閉包 什么是閉包

閉包,是一個具有封閉功能與包裹功能的一個結(jié)構(gòu)或空間。在js中,函數(shù)可以構(gòu)成閉包。因為函數(shù)在當(dāng)前的作用域中是一個封閉的結(jié)構(gòu),具有封閉性;同時根據(jù)作用域規(guī)則,只允許函數(shù)內(nèi)部訪問外部的數(shù)據(jù),而外部無法訪問函數(shù)內(nèi)部的數(shù)據(jù),即函數(shù)具有封閉的對外不公開的特性,就像把一個東西包裹起來一樣,因此函數(shù)可以構(gòu)成閉包。

有點難理解,簡單來說,就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù),再簡潔一點就是:定義在一個函數(shù)內(nèi)部的函數(shù)。

閉包的基本結(jié)構(gòu)

因為閉包不允許外界直接訪問,所以只能間接訪問函數(shù)內(nèi)部的數(shù)據(jù),獲得函數(shù)內(nèi)部數(shù)據(jù)的使用權(quán)。

1、寫一個函數(shù),函數(shù)內(nèi)定義一個新函數(shù),返回新函數(shù),用新函數(shù)獲得函數(shù)內(nèi)部的數(shù)據(jù)
function foo(){
  var num = 123;
  function func(){
    return num;
  }
  return func;
}
var f = foo();
var res1 = f();
var res2 = f(); 
// 此時,foo只調(diào)用了一次,不會再內(nèi)存中重新創(chuàng)建一個函數(shù),而通過f,可以訪問并獲取num的值,那么調(diào)用f,即可獲得一樣的num值

改良:
function foo(){
  var num = 123;
  return function(){
    return num;
  }
}
var f = foo();
var res1 = f();
var res2 = f();

再改良:
var f = (function foo(){
  var num = 123;
  return function (){
    return num;
  }
})();
var res1 = f();
var res2 = f();
2、寫一個函數(shù),函數(shù)內(nèi)定義一個對象,對象綁定一個或多個函數(shù)(方法),返回對象,利用對象的方法訪問函數(shù)內(nèi)部的數(shù)據(jù)
function func(){
  var num1 = Math.random();
  var num2 = Math.random();
  return {
    num1: function(){
      return num1;
    },
    num2: function(){
      return num2;
    }
  }
}
var p = func();
console.log(p.num1());
console.log(p.num1());// 這兩個訪問到的是同一個隨機數(shù)
閉包的基本用法

如上面代碼演示的那樣,閉包可以通過返回函數(shù)來間接訪問到函數(shù)內(nèi)的數(shù)據(jù),這樣,閉包可以實現(xiàn)具有私有訪問空間的函數(shù),保護私有的數(shù)據(jù)。另一方面,可以幫助其他對象讀取到函數(shù)內(nèi)部的變量

閉包的性能問題

函數(shù)定義的變量會在函數(shù)執(zhí)行結(jié)束后自動回收,但是因為閉包結(jié)構(gòu)引出的數(shù)據(jù)經(jīng)常會被外界所引用,這些數(shù)據(jù)將不會被回收,因此過多的閉包會消耗內(nèi)存資源,影響性能。所以要謹(jǐn)慎使用閉包,可以在使用閉包時,如果不再使用某些變量了,一定要賦值一個null。

在ES6中,提出來對象代理概念,在代理層操作數(shù)據(jù)而不是直接操作原數(shù)據(jù)。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/100263.html

相關(guān)文章

  • 這一次,我們換種姿勢學(xué)習(xí) javascript

    摘要:操作符或調(diào)用函數(shù)時傳入?yún)?shù)的操作都會導(dǎo)致關(guān)聯(lián)作用域的賦值操作。此外可以使用和來設(shè)置對象及其屬性的不可變性級別。忽視這一點會導(dǎo)致許多問題。使用調(diào)用函數(shù)時會把新對象的屬性關(guān)聯(lián)到其他對象。 前言 《你不知道的 javascript》是一個前端學(xué)習(xí)必讀的系列,讓不求甚解的JavaScript開發(fā)者迎難而上,深入語言內(nèi)部,弄清楚JavaScript每一個零部件的用途。本書介紹了該系列的兩個主題:...

    zone 評論0 收藏0
  • 20170917 前端開發(fā)周報:JavaScript函數(shù)式編程、作用域和閉包

    摘要:用函數(shù)式編程對進行斷舍離當(dāng)從業(yè)的老司機學(xué)會函數(shù)式編程時,他扔掉了的特性,也不用面向?qū)ο罅?,最后發(fā)現(xiàn)了真愛啊作用域和閉包作用域和閉包在里非常重要。旨在幫助非函數(shù)式編程的同學(xué),能快速切入到函數(shù)式編程的理念。 1、用函數(shù)式編程對JavaScript進行斷舍離 當(dāng)從業(yè)20的JavaScript老司機學(xué)會函數(shù)式編程時,他扔掉了90%的特性,也不用面向?qū)ο罅耍詈蟀l(fā)現(xiàn)了真愛?。。?! https:/...

    tomener 評論0 收藏0
  • 20170917 前端開發(fā)周報:JavaScript函數(shù)式編程、作用域和閉包

    摘要:用函數(shù)式編程對進行斷舍離當(dāng)從業(yè)的老司機學(xué)會函數(shù)式編程時,他扔掉了的特性,也不用面向?qū)ο罅?,最后發(fā)現(xiàn)了真愛啊作用域和閉包作用域和閉包在里非常重要。旨在幫助非函數(shù)式編程的同學(xué),能快速切入到函數(shù)式編程的理念。 1、用函數(shù)式編程對JavaScript進行斷舍離 當(dāng)從業(yè)20的JavaScript老司機學(xué)會函數(shù)式編程時,他扔掉了90%的特性,也不用面向?qū)ο罅耍詈蟀l(fā)現(xiàn)了真愛?。。?! https:/...

    cyixlq 評論0 收藏0
  • 20170917 前端開發(fā)周報:JavaScript函數(shù)式編程、作用域和閉包

    摘要:用函數(shù)式編程對進行斷舍離當(dāng)從業(yè)的老司機學(xué)會函數(shù)式編程時,他扔掉了的特性,也不用面向?qū)ο罅耍詈蟀l(fā)現(xiàn)了真愛啊作用域和閉包作用域和閉包在里非常重要。旨在幫助非函數(shù)式編程的同學(xué),能快速切入到函數(shù)式編程的理念。 1、用函數(shù)式編程對JavaScript進行斷舍離 當(dāng)從業(yè)20的JavaScript老司機學(xué)會函數(shù)式編程時,他扔掉了90%的特性,也不用面向?qū)ο罅?,最后發(fā)現(xiàn)了真愛啊?。?! https:/...

    lentoo 評論0 收藏0
  • 深入javascript——作用域和閉包

    摘要:注意由于閉包會額外的附帶函數(shù)的作用域內(nèi)部匿名函數(shù)攜帶外部函數(shù)的作用域,因此,閉包會比其它函數(shù)多占用些內(nèi)存空間,過度的使用可能會導(dǎo)致內(nèi)存占用的增加。 作用域和作用域鏈?zhǔn)莏avascript中非常重要的特性,對于他們的理解直接關(guān)系到對于整個javascript體系的理解,而閉包又是對作用域的延伸,也是在實際開發(fā)中經(jīng)常使用的一個特性,實際上,不僅僅是javascript,在很多語言中都...

    oogh 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<