国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

The Little JavaScript Closures

Heier / 2945人閱讀

摘要:寫在前面本文嘗試模仿的風格,介紹的閉包。本文同時也是我學習閉包的一次總結。注根據這篇文章,事實上所有函數在創建的時候都會形成閉包。但這種閉包并沒什么趣味,也沒什么特別的用途,所以我們更關注的是由內部函數形成的閉包。

寫在前面

本文嘗試模仿 The Little Schema 的風格,介紹 JavaScript 的閉包。本文同時也是我學習 JavaScript 閉包的一次總結。歡迎一起討論。

簡介

什么是閉包?

閉包是一個函數

閉包都是函數嗎?

函數都是閉包嗎?

我怎么判斷一個函數是不是閉包?

你現在還不能回答,因為你還不知道以下概念:
全局變量(Global Variable)
局部變量(Local Variable)
自由變量(Free Variable)
詞法作用域(Lexical Scope)

變量與作用域

var a = 1; a 是什么變量?

全局變量

a = 1; a 是什么變量?

全局變量

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

這里的 a,b 分別是什么變量?

a 是全局變量,b 是局部變量

為什么 a 在函數中定義還是全局變量?

因為 a 不是用 var 聲明的

不用 var 聲明的變量都是全局變量?

是的

var 聲明的變量都是局部變量?

不是

為什么?

在全局作用域中聲明的變量都是全局變量,即使這個變量是用 var 聲明的

全局作用域是什么?

函數作用域以外的地方都是就是全局作用域

函數作用域又是什么?

函數內部

可以舉個例子嗎?

var foo = 1;
function bar() {
  var baz = 2;
}

foo 變量和 bar 函數都處于全局作用域中,baz 變量處于函數作用域中

function foo() {
  var bar = 1;
}

這段代碼中有多少個作用域?

2 個,foo 函數所處的全局作用域和 bar 變量所處的函數作用域

function foo() {
  var bar = 1;
  function baz() {
    var test = 1;
  }
}

這段代碼中有多少個作用域?

3 個,foo 函數所處的全局作用域,bar 所處的函數作用域,和 test 所處的函數作用域

上面的 bar 變量和 baz 函數處于同一個作用域嗎?

是的,因為它們都在 foo 函數中

上面 test 變量和 bar,baz處于同一個作用域中嗎?

不是,因為 test 變量在 baz 函數中

JavaScript 用函數來劃分作用域嗎?

是的

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

會輸出什么?

Uncaught ReferenceError: bar is not defined

為什么會報錯呢?

因為外部作用域不能訪問內部作用域

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

會輸出什么?

1

為什么不會報錯?

因為內部作用域可以訪問外部作用域

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

會輸出什么?

2

為什么不是輸出 1 ?

因為局部變量的優先級比外部變量高

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

會輸出什么?

undefined
2

為什么會這么奇怪?

因為變量聲明有變量提升(Variable Hoisting)的過程

變量提升是什么?

聲明語句會在執行前被處理,在任何地方聲明一個變量,相當于在頂部位置聲明

可以舉個例子嗎?

bla = 0;
var bla;

// 相當于

var bla;
bla = 0;

這和之前的例子有什么關系?

函數內部聲明的變量,都會先在函數的頂部聲明。所以之前的例子就相當于

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

什么是詞法作用域?

變量的作用域是由它在源代碼中所處位置決定的(詞法),并且嵌套的函數可以訪問到其外層作用域中聲明的變量。

這和上面說到的內部作用域可以訪問外部作用域有什么區別嗎?

沒有

什么是自由變量?

在函數內部使用到,但既不是該函數的參數,也不是該函數的局部變量的變量。

可以舉個例子嗎?

var foo = 1;
function bar() {
  var baz = 2;
  console.log(foo + baz);
}

這里 bar 函數有三個變量:baz, console, foo
其中 baz 是局部變量, console 和 foo 都屬于自由變量

為什么 console 和 foo 都是自由變量?

因為 console 和 foo 都在全局作用域中,在 bar 函數中是通過引用的方式來使用 console 和 foo 的

還需要了解其他概念嗎?

不需要,現在已經可以深入了解閉包了

閉包

什么是閉包?

閉包是一個內部函數 [注1]

內部函數都是閉包嗎?

不是,引用了自由變量的內部函數才是閉包

var x = 1;
function foo() {
  console.log(x + 1);
}

foo 函數是一個閉包嗎?

不是,因為 foo 函數不是一個內部函數

function foo() {
  function bar() {
    var x = 1;
    return x + 1;
  }
}

bar 函數是一個閉包嗎?

不是,因為它只是一個內部函數,并沒有引用自由變量

function foo() {
  var x = 1;
  function bar() {
    return x + 1;
  }
}

bar 函數是一個閉包嗎?

是的,因為它是一個內部函數,同時引用了自由變量

閉包有什么特點?

閉包可以訪問外部變量

閉包可以在外部函數返回之后依然保留外部變量的引用

閉包會保留外部變量的引用,不是該變量的值

第一點在前面的例子中已經懂了。

很好

第二點還沒懂,可以舉個例子嗎?

function add(x) {
  return function(y) {
    return x + y;
  }
}

var add5 = add(5);
console.log(add5(10)) // 15

即便 add 函數已經返回,add5 中依然可以訪問 x

第三點還沒懂,可以舉個例子嗎?

function user() {
  var id = 1;

  return {
    getId: function() { return id; },
    setId: function(newId) { id = newId }
  }
}

var foo = user();
foo.getId(); // 1
foo.setId(2);
foo.getId(); // 2

這里閉包中的 id 是一個引用,不是實際值

有點像私有方法?

是的,我們可以用閉包來實現私有方法

閉包還可以用來做什么?

閉包是函數式編程的骨架,掌握閉包之后你可以寫出函數式 JavaScript 代碼。

函數式編程是什么?

這不是本文的討論范圍,自己去學習吧。

One More Thing

注1] 根據 [Understanding JavaScript Closures 這篇文章,事實上所有函數在創建的時候都會形成閉包。但這種閉包并沒什么趣味,也沒什么特別的用途,所以我們更關注的是由內部函數形成的閉包。

出處

https://scarletsky.github.io/2015/12/02/...

參考資料

http://uternet.github.io/TLS/
http://www.ruanyifeng.com/blog/2009/08/l...
https://developer.mozilla.org/zh-CN/docs...
https://developer.mozilla.org/en-US/docs...
http://javascriptissexy.com/understand-j...
http://javascriptissexy.com/javascript-v...
http://stackoverflow.com/questions/12930...
https://javascriptweblog.wordpress.com/2...
http://www.moye.me/2014/12/29/closure_hi...

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/78258.html

相關文章

  • JavaScript之閉包相關

    摘要:函數對象可以通過這個作用域鏈相互關聯起來,如此,函數體內部的變量都可以保存在函數的作用域內,這在計算機的文獻中被稱之為閉包。所以按照第二段所說的,嚴格意義上所有的函數都是閉包。 Like most modern programming languages, JavaScript uses lexical scoping. This means that functions are e...

    sewerganger 評論0 收藏0
  • 分享一個關于匿名函數和閉包的問答

    摘要:引用一個的提問個人覺得總結的比較好的兩句話原文地址另外,附上中對閉包的講解閉包中文對于閉包的簡要概括原文原文地址匿名函數和閉包來自文章作者版權聲明自由轉載非商用非衍生保持署名創意共享許可證轉載請注明出處 引用一個stackoverflow的提問 個人覺得總結的比較好的兩句話: An anonymous function is just a function that has no na...

    Barrior 評論0 收藏0
  • 掌握Javascript面試:什么是閉包?

    摘要:我的意思是大多數稱職的面試官會問你什么是閉包,并且在大多數時候你回答錯誤將失去這份工作。在閉包的范圍內定義的任何公開方法都是特權的。使對象的數據私有化并不是閉包的唯一用途。 文章來源于:https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-closure-b2f0d2152b36 在J...

    jifei 評論0 收藏0
  • javascript閉包介紹

    摘要:下面這個例子就是閉包,函數能夠訪問到不在其代碼塊里的變量。然而事實恰恰相反,唯一的解釋就是是一個閉包。性能問題執行一次,就會重新構造兩個函數。正確的做法應該是參考資料深入理解閉包學習閉包阮一峰 概念 閉包(closure)是一個擁有任意變量以及綁定這些變量的環境(environment)的表達式(一般來說是就是function) A closure is an expression (...

    weij 評論0 收藏0
  • JavaScript 語法樹與代碼轉化實踐

    摘要:語法樹與代碼轉化實踐歸納于筆者的現代開發語法基礎與實踐技巧系列文章中。抽象語法樹抽象語法樹的作用在于牢牢抓住程序的脈絡,從而方便編譯過程的后續環節如代碼生成對程序進行解讀。 JavaScript 語法樹與代碼轉化實踐 歸納于筆者的現代 JavaScript 開發:語法基礎與實踐技巧系列文章中。本文引用的參考資料聲明于 JavaScript 學習與實踐資料索引中,特別需要聲明是部分代碼片...

    Gemini 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<