本节接着上一篇谈谈function scope 函数域和闭包
首先,先明确2条基本规则。
1 定义在function之内的变量不能被function外任何地方访问到,因为该变量只被定义在function的域中。
var createPet = function() {
var name = 'cat';//定义变量name
};
console.log(createPet.name);//这样不行的,这个name你在createPet外部是无论如何也访问不到的。
除非
var createPet = function() {
var name = 'cat';// defines a variable called "name"
return name;
};
console.log(createPet());// 正确返回cat,但这种解决方案不是本文要说的重点。
2 function内部定义的function不仅可以访问本域中的所有变量和函数,还可以访问父域的所有变量和函数。
function getScore () {
var num1 = 2,
num2 = 3;
function add() {
return name + " scored " + (num1 + num2);
}
return add();
}
getScore(); // 返回 "Chamahk scored 5"
由于上边的2条规则,外部function和变量会比内部function和变量的声明周期长,如果想让内部function“活”的超过外部function,可以通过创建闭包来实现,闭包可以让内部function对所有域可用。
var pet = function(name) {
var getName = function() {
return name;
}
return getName; // 返回内部function,把他暴露给外部的域
},
myPet = pet("Vivie");
myPet(); // 返回 "Vivie"
在上边的代码中,变量name可以并仅可以通过内部function来访问。内部function中的变量是“持久的” ,安全的。 甚至function不需要非得有个名字。
var getCode = (function(){
var secureCode = "0]Eal(eh&2"; //secureCode是只读的
return function () {
return secureCode;
};
})();
getCode();
当然也有很多陷阱,如果内部function中的变量和外部function中的变量重名,那么再也无法访问到外部的那个变量了。
var createPet = function(name) { //外部function定义的name
return {
setName: function(name) { //重名的name
name = name; // ??? 要如何访问到外部的name ???
}
}
}
因为setName会先在自己的域中寻找name,如果没有找到,才到上层域中寻找name
未完待续。。。