js:深入閉包(作用域:下)

function fn1(){
//創建瞭一個數組
var fns = new Array();
//i這個變量是保存在fn1這個作用域中
for(var i=0;i<10;i++){
//數組中的值是一組函數
fns[i] = function(){
return i;
}
}
return fns;
}

var fs = fn1();
for(var i=0;i<fs.length;i++){
//此時通過閉包來調用所有的函數,當要輸出i的時候會在它所在的定義域(fn1)中找到它,
//此時它已變為10,所以連續輸出瞭10個10
console.log(fs[i]());
} //輸出:10

—————————解決方案——————————
function fn1(){
//創建瞭一個數組
var fns = new Array();
//i這個變量是保存在fn1這個作用域中
for(var i=0;i<10;i++){
//num這個變量保存在tf作用域,每一個閉包的num都是不一樣的
//所以此時所消耗的內存較大。
var tf = function(num){
fns[num] = function(){
return num;
}
}
tf(i);
}
return fns;
}

var fs = fn1();
for(var i=0;i<fs.length;i++){
//
console.log(fs[i]());
} //輸出:0 ~ 9

—————————塊作用域——————————
for(var i=0;i<10;i++){

}
//在js中沒有塊作用域,不管是使用循環還是判斷之後,這個變量一直存在
/**
* 所以當在全局使用某個變量進行循環或判斷之後,這個變量可能會影響到函數的變量,所以
* 所以在特殊情況下不要使用全局變量,而且全局變量在作用域鏈的最上層,訪問是最慢的。
*/
console.log(i);
function fn1(){
console.log(i);
}
fn1();

/**
* 在一個團隊進行開發中,可能會涉及到定義同名的全局變量,所以在開發中要養成一個好習慣:
* 將全局變量代碼放到一個匿名函數,並且馬上調用匿名函數,這樣也可以執行全局變量的代碼。
* 但是這些變量被控制在開發人員想要控制的作用域中。
*/
解決辦法:將塊作用域定義在一個匿名函數中。
(function(){
for(var i=0;i<10;i++){

}
})(); //在function的{}後不能直接調用,一定要加把匿名函數放在()內再執行。

—————————私有變量——————————
function Person(name){
/**
*此時沒有辦法直接訪問name這個屬性,因為沒有this.name,
*要訪問name隻能通過this.getName獲取,通過this.setName設置
*/
this.setName = function(value){
name = value;
}
this.getName = function(){
return name;
}
}

var p = new Person(“zhang”); //zhang
console.log(p.getName());
p.setName(“li”);
console.log(p.getName()); //li

/**但是使用這種方式創建私有變量帶來的問題是每個對象要存儲大量函數。
* 解決的方法是通過靜態私有變量來解決。
*/
—————————解決方案——————————
var Person;
(function(){
//name在函數結束之後就消失,在外面無法使用
var name = “”;
Person = function(value){
name = value;
}
Person.prototype.setName = function(value){
name = value;
}
Person.prototype.getName = function(){
return name;
}
})();

var p1 = new Person(“aaa”); //aaa
console.log(p1.getName());
p1.setName(“bbb”); //bbb
console.log(p1.getName());

原創文章如轉載,請註明出處,本文首發於csdn網站:https://blog.csdn.net/magneto7/article/details/25459099

發佈留言