閉包用法的陷阱
前言
最近有個關於閉包的bug,找了相當的久才找到,這裡做個紀錄。
內容
首先先看以下程式碼var obj={ name:"MyObj", data:[1,2,3,4,5] }; function printObjectData(data){ return function(){ console.log(data); }; } // var printFun = printObjectData(obj.data); printFun(); obj.data = []; console.log("Clear data!"); printFun();
最後console的結果如下
[1, 2, 3, 4, 5] Clear data! [1, 2, 3, 4, 5]
可以看到最後一次的printFun()竟然沒有清除資料!本以為可能是javascript的array是pass by value造成的,但實際試驗了一下javascript會發現array是pass by reference,那這到底是什麼問題呢?實際上是這樣的,printFun在從 printObjectData()取得function時,確實是得到obj.data,但問題是接下來的clear,也就是"obj.data = []",這個array的清除有問題,這裡確實清除了obj.data,但閉包裡的data還是舊的array,所以會發現第二次的printFun()依舊是原本的array,問題是說"obj.data = []"的意思其實不是clear一個array,而是將obj.data指向一個空array。如果要修正問題改成以下
var obj={ name:"MyObj", data:[1,2,3,4,5] }; function printObjectData(obj){ return function(){ console.log(obj.data); }; } // var printFun = printObjectData(obj); printFun(); obj.data=[]; console.log("Clear data!"); printFun();
沒有留言:
張貼留言