需求:
*比如我们通过js构建一个商品对象,初始化传入商品ID。
该对象里面有个方法,该方法假设要通过『有逼格』的计算才能获获取商品名称*
1.
<script type="text/javascript">
var product = function(id){
var prodID = id;
this.prodName = "药品"; //这个属性外部可以访问
function loadProd(){ //这个方法不希望外部访问
//假设这个过程需要复杂的计算
if (prodID == 1) {
this.prodName = "霸王油";
}else if (prodID == 2) {
this.prodName = "老鼠药";
}
}
}
var p1 = new product(1);
alert(p1.prodName); //打印:药品
</script>
并没有获取到我们认为的『霸王油』, 这是因为实例化后的p1并不能调用loadProd这个方法。
2.所以我们只能在内部调用
var product = function(id){
var prodID = id;
this.prodName = "药品"; //这个属性外部可以访问
function loadProd(){ //这个方法不希望外部访问
//假设这个过程需要复杂的计算
if (prodID == 1) {
this.prodName = "霸王油";
}else if (prodID == 2) {
this.prodName = "老鼠药";
}
}
loadProd(); //内部调用啦
}
var p1 = new product(1);
alert(p1.prodName); //打印:药品
上面代码还是弹出『药品』,这是因为loadProd()函数内部的this并不是我们传入的。
优化:
var product = function(id){
var prodID = id;
this.prodName = "药品"; //这个属性外部可以访问
function loadProd(oo){ //这个方法不希望外部访问
//假设这个过程需要复杂的计算
if (prodID == 1) {
oo.prodName = "霸王油";
}else if (prodID == 2) {
oo.prodName = "老鼠药";
}
}
loadProd(this); //传入this
}
var p1 = new product(1);
alert(p1.prodName); //打印:霸王油
var p2 = new product(2);
alert(p2.prodName); //打印:老鼠药
3.闭包的写法
var product = function(id){
var prodID = id;
var prodName = "药品";
function loadProd(){ //这个方法不希望外部访问
//假设这个过程需要复杂的计算
if (prodID == 1) {
prodName = "霸王油";
}else if (prodID == 2) {
prodName = "老鼠药";
}
return prodName; // 返回私有变量
}
return loadProd; //返回函数本身
}
var p1 = new product(1);
alert(p1()); //p1() 就是执行了loadProd(),结果打印:霸王油
再次优化:
var product = function(id){
var prodID = id;
var prodName = "药品";
return function loadProd(){ //这个方法不希望外部访问
//假设这个过程需要复杂的计算
if (prodID == 1) {
prodName = "霸王油";
}else if (prodID == 2) {
prodName = "老鼠药";
}
return prodName; // 返回私有变量
}
}
var p1 = new product(1);
alert(p1()); //结果打印:霸王油
简单总结:
1.内部function访问了外部变量
2.内部函数维持了外部函数(对象)的数据
3.闭包本身是为了简化代码、减少过多的人工细节参与
<script type="text/javascript">
var product = function(id){
var prodID = id;
var prodName = "药品";
return function loadProd(){ //这个方法不希望外部访问
//假设这个过程需要复杂的计算
if (prodID == 1) {
prodName = prodName + "霸王油"; // 内部函数也可以使用外部函数的数据
}else if (prodID == 2) {
prodName = prodName +"老鼠药";
}
return prodName; // 返回私有变量
}
}
var p1 = new product(1);
alert(p1()); //结果打印:药品霸王油
</script>