1. 程式人生 > >關於閉包和javascript函式表示式的一點理解

關於閉包和javascript函式表示式的一點理解

前言:看了很多閉包的部落格,總結一下。也是對自己的一種鍛鍊和加深自己的理解。前端自學中,歡迎大家指點,謝謝~

一、函式表示式

定義函式表示式的方式有兩種:一種是函式宣告,一種是函式表示式

1.函式宣告

function fun() {
//函式體
}

用函式宣告去定義一個函式用關鍵字function,後面加函式名,用name屬性可以得到函式名

alert(fun.name);//fun

函式宣告最重要的特徵是函式宣告提升,通俗一點就是說可以把函式宣告可以放在函式呼叫後面。

sayhi();
function sayhi() {
}

2.函式表示式

var sayhi = function() {
//函式主體
}

函式表示式的呼叫不能在函式表示式之前,必須在後面。

二、閉包

為什麼在介紹閉包之前要寫函式宣告方式呢?那接下來我要講的和這個有關係

首先講一下聲什麼是閉包,《javascript高階程式設計設計》裡面是這樣定義的:閉包是指有權訪問另一個函式作用域中的變數的函式。那按照這句話的意思就是閉包是一個函式咯,網上很多關於閉包的文章都提到閉包的本質是一個連線函式內部和外部的橋樑。所以閉包有兩個作用:一是讀取函式內部的變數。而是讓這些變數一種保持在記憶體中。

先給出一個問題吧?

怎麼去實現將數字0~9每過一秒依次彈出?

舉個例子:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>閉包</title>
  </head>
  <body>
  </body>
  <script type="text/javascript">
    function fun() {
      for (var i = 0; i < 10; i++) {
         (function(i){
           setTimeout(function(){
            alert(i);
           },(i+1)*1000);
         })(i);
        }
      }
    fun();
  </script>
</html>

執行上面的函式,得到的結果是每過一秒依次輸出0,1,2,3,4,5,6,7,8,9

換一種寫法,如下

      for (var i = 0; i < 10; i++) {
          setTimeout(function(){
            alert(i);
          },(i+1)*1000)
        }

得到的結果是每過一秒依次輸出10,10,10,10,10,10,10,10,10

為什麼會這樣?匿名函式裡面的alert(i)可以讀取到外部函式的i值,這就是閉包。兩種寫法都可以得到讀取到i,但第一種可以得到每一次for迴圈的i值,第二張卻不行呢?

這一點我認為和閉包沒關係,但是我看過的很多關於閉包的文章都把這兩點混為一談,下面是我的一點理解

先說為什麼第二種不行,setTimeout定時函式裡面的回撥函式function它只是宣告函數了,但沒有呼叫(這也是為什麼開始講函式宣告和函式呼叫),所以每次for迴圈的時候,i都在變化,而function沒有執行。只有在for迴圈執行完i = 10的時候,定時函式呼叫了這個匿名函式。所以輸出都是10.

那第一種為什麼可以?第一中在setTimeout函式外部用一個匿名函式,然後讓它自執行,傳入引數i,當for迴圈的時候,i傳入匿名函式的時候會複製一份變數i,也就是i從0到9都複製保持在該匿名函式的作用域中,故定時函式裡的匿名函式可以正確輸出i。

最後,歡迎大家指正和討論,祝大家技術進步,早日成為大神!

相關推薦

關於javascript函式表示式一點理解

前言:看了很多閉包的部落格,總結一下。也是對自己的一種鍛鍊和加深自己的理解。前端自學中,歡迎大家指點,謝謝~一、函式表示式定義函式表示式的方式有兩種:一種是函式宣告,一種是函式表示式1.函式宣告function fun() { //函式體 }用函式宣告去定義一個函式用關鍵字f

好程式設計師前端教程之JavaScript匿名函式的關係詳解

開發十年,就只剩下這套架構體系了! >>>   

JS(二)-箭頭函式

(一)閉包 一、函式作為返回值 高階函式除了可以接受函式作為引數外,還可以把函式作為結果值返回。 求和的函式定義: function sum(arr) {     return arr.reduce(function (x, y) {         return x +

全面理解Javascript的幾種寫法及用途【轉】

內部 ron 除了 因此 擁有 否則 這一 sage ssa 一、什麽是閉包和閉包的幾種寫法和用法 1、什麽是閉包 閉包,官方對閉包的解釋是:一個擁有許多變量和綁定了這些變量的環境的表達式(通常是一個函數),因而這些變量也是該表達式的一部分。閉包的特點:  1. 作為一個函

全面理解Javascript的幾種寫法及用途

  好久沒有寫部落格了,過了一個十一長假都變懶了,今天總算是恢復狀態了。好了,進入正題,今天來說一說javascript裡面的閉包吧!本篇部落格主要講一些實用的東西,主要將閉包的寫法、用法和用途。  一、什麼是閉包和閉包的幾種寫法和用法 1、什麼是閉包 閉包,官方對

javascript分析回撥函式

<div id="box1">First Box</div> <div id="box2">Second Box</div> <script> function animateIt(elementId) { var el

javascript立即執行函式

閉包—closure 先看一個閉包的例子。我們想實現一個計數器,最簡單的方法就是定義一個全域性變數,計數的時候將其加1。但是全域性變數有風險,哪裡都有可能不小心改掉它。那區域性變數呢,它只在函式內部有效,函式呼叫完後它就沒了,而且全域性沒法使用。那我們用想讓計數器全域性使用

JavaScript關於,匿名函式,this,物件等的一些理解

        閉包原本就是指所有的函式,但我們一般是指能夠讀取其他函式內部變數的函式,主要有兩個作用:一個是可以讀取函式內部的變數,另一個就是讓這些變數的值始終保持在記憶體中。當函式a的內部函式b被函式a外的一個變數引用的時候,就建立了一個閉包。匿名函式不但可以省去命名的

javascript學習:prototype原型使用基礎

c# 作用 cnblogs public return rem 聲明 pre 都是 閉包 function Person(name) { this.Username = name; var Userage = 18;

JavaScript學習總結(三、函數聲明表達式、this、引用、arguments對象、函數間傳遞參數)

rem [1] incr foo i++ scrip erro ren 推薦 一、函數聲明和表達式 函數聲明: function test() {}; test(); //運行正常 function test() {}; 函數表達式: var test = fun

JavaScript中的作用域鏈

com inf asc 分享 size bsp 手冊 部分 rip 這部分幾乎是JavaScript中最難的部分,也是面試官最愛問的地方。 下面的內容是我以前寫的《JavaScript學習手冊》中被客戶刪除的部分,理由聽起來有點詭異:太難。

javascript this 匿名函式 匿名物件

var a = function (){       function g(){        console.log("g:"+this);    &nbs

一個關於javascriptthis的題目

##1. var name = "The Window"; var object = { name: "My Object", getNameFunc: function(){ return this.name; } } 問:object.getNam

、箭頭函式、generator JavaScript邊學邊記(五)

閉包:函式 + 建立函式的詞法環繞的組合 函式除了可以接受函式作為引數,還可以將函式作為結果值返回。返回的是函式,而不是結果。 可以類比於Java中類,只有一個公共方法(閉包中返回的函式)的類類似於閉包。 function make_sum(arr) {

【慕課網】JavaScript作用域

1.閉包 阮一峰部落格閉包文章:http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html 類是有行為的資料,閉包是有資料的行為。 一、變數的作用域 要理解閉包,首先必須理解Jav

C#——委託、Lambda表示式記憶體洩漏

使用委託的典型情況 首先看看委託的常見的使用情景:定義一個委託、使用剛定義的委託宣告一個委託變數、根據需要將方法和該變數繫結,最後在合適的地方使用它。程式碼形式如下: //定義委託 public delegate void SomeDelegate(); cla

函式中的裝飾器

重新學習完了函式,是時候將其中的一些重點重新捋一捋了,本次總結的東西只有閉包和裝飾器 1.閉包 閉包是函式中的一個比較重要功能,一般閉包都是用在裝飾器上,一般學完閉包就會去學習裝飾器,這倆個總是讓初學時的我一臉懵逼,現在好好捋一捋。   1.1 閉包的定義 內層函式對外層函式(非全域性)呼叫

關係規範化之函式依賴集屬性集X對於函式依賴集F的

最近在學資料庫原理,關係規範化中介紹了幾個演算法,最基礎也最重要的就是求屬性集X關於某個函式依賴集合F的閉包。 /*8周的功夫一本資料庫基本原理就學完了,很快要考試了,所以5-1假期也沒打算出去玩,就在學校了複習、休息等等。就在複習的過程中,突然發現書上對於函式依賴集合的閉

資料庫基礎(4)函式依賴公理推論(Armstrong公理),屬性求候選鍵的技巧

函式依賴裡面,函式依賴公理,Armstrong公理以及屬性閉包的定義都有必要仔細學習 1.邏輯蘊含基本定義 2.Armstrong公理和推論–可以用來判斷一個函式依賴X -> Y 是否邏輯蘊含

Lua,JavaScript迭代器筆記

在JS中一直不太理解閉包這個概念 ,有幸在學習lua程式設計中重新理解了下閉包和迭代器 這個是書上的原文: 迭代器是一種支援指標型別的結構,它可以遍歷集合的每一個元素。在 Lua 中我們 常常使用