您的位置 >>> 星想互聯 >>> 編程技術 >>> PHP基礎
深刻理解閉包,php中的closure使用詳解
點擊數:69  發布時間2020-06-06 22:49:39
Closure英文在計算機術語中是閉包的意思。PHP手冊中又解釋Closure是用于代表匿名函數的類.。
匿名函數,顧名思義是沒有名字的函數。其中,匿名函數也叫閉包函數。
閉包,在百度百科中的意思是能夠讀取其他函數內部變量的函數。
而在php中,別人會告訴你,閉包的功能是內部函數中可以使用外部變量。那么誰是對的呢?
那我們來了解一下。

$closure = function(){echo "hello";}; // 首先我們創建一個匿名函數
var_dump($closure); // 輸出object(Closure)#1 (0) { }

$closure(); // 輸出hello


由此我們可以看出創建一個匿名函數,實際上是創建了一個Closure類的對象。
所以closure其實是一個偽裝成函數的對象。

匿名函數很好理解,那么什么是閉包呢?

首先,比如我們在下面模擬一個計數器功能,在php中我們想用一個函數去訪問外部的變量。
代碼如下:

//直接訪問
$count = 0;
function add(){
echo $count++;
}
add(); // error  無法調用$count,提示Undefined variable: count

//接下來我們試著用匿名函數來實現
$count = 0;
$add = function(){
echo $count++;
};
$add(); // error  依然無法調用$count,提示Undefined variable: count

//通過關鍵字use來鏈接函數與外部變量
$count = 0;
$add = function() use($count){
echo $count++;
};
$add(); // 0  可以訪問$count了
$add(); // 0  但$count依然是0,但我們想讓數目增加。哦,原來$count只是一份副本,要$count保存原值進行操作要加上&

//然后,我們在use括號里加上&
$count = 0;
$add = function() use(&$count){
echo $count++;
};
$add(); // 0
$add(); // 1  終于成功了!
$add(); // 2 繼續累加


但是呢?上面的count是一個全局變量,任何外部方法都可以去改變它,為確保獨立性。比如是一篇文章的瀏覽次數。
我們將count放入一個函數中。以下:

function add(){
$count = 0;
return function() use(&$count){echo $count++;};
}
$a=add();
$a(); // 0
$a(); // 1

這也是成功的。我們理解了,閉包的實現的功能的確是內部函數中可以使用外部變量。

那么,接下來我們,比較一下javascript代碼與php代碼的區別

//javascript代碼
function a(){
var i=0;
function b(){
alert(++i);
}
return b;
}
var c=a();
c(); // 1
c(); // 2

對比上述兩種語言的代碼,實現了相同的功能。

在JavaScript中,函數a的嵌套函數b由于作用域鏈的關系,能夠讀取它的外部變量i,嵌套函數是由名字的。
而在php中,這必須通過use關鍵字來鏈接外部變量,并且函數本身是沒名字的。
當然對于外部來說,js代碼的函數c的確是能夠讀取其他函數(a)的內部變量(i)的函數,當然它的本質是函數b。
在上述php代碼中,函數a也的確是能夠讀取其他函數(add)的內部變量($count)的函數,它的本質當然也是閉包函數。

所以,雖然說法不同,但兩者都實現了閉包,說的是同樣的意思。

接下來,我們創建一個參數完整的閉包函數,看看closure里面到底有什么。

//首先創建了一個Apple類
Class Apple{
public static $name = "apple";
public $color ="red";
private $money = 10;
public function getClosure(){
$ex1 = self::$name;
$ex2 = $this->money;
return function($name) use($ex1,$ex2){
echo $name."買了".$ex1."花了".$ex2;
};
}
}
$apple = new Apple();
$c =$apple->getClosure();
var_dump($c); //輸出閉包。

//輸出格式如下
object(Closure)#2 (3) {
["static"]=>
array(2) {
["ex1"]=>
string(5) "apple"
["ex2"]=>
int(10)
}
["this"]=>
object(Apple)#1 (2) {
["color"]=>
string(3) "red"
["money":"Apple":private]=>
int(10)
}
["parameter"]=>
array(1) {
["$name"]=>
string(10) "
"
}
}

從個上述的格式上來看,一個參數齊全的閉包自動添加了三個屬性,分別是:static,this和parameter。
閉包引用的外部變量參數自動給了static屬性。
同時,閉包所屬的對象也就是apple對象自動給了一個this屬性。
閉包所需要輸入的參數自動給了parameter屬性,并且提示需要等待輸入。

我們看到在php中閉包的實現,用的都是沒有名字的函數,所以匿名函數也叫閉包函數。
————————————————
版權聲明:本文為CSDN博主「曉風殘月淡」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_40610003/java/article/details/99312506
來源:咸寧網站建設
日本高清成 人,A级高清毛片av无码,欧美成 人 免费在线播放-首页 <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>