一 閉包的特點
- 函數(shù)嵌套函數(shù)
- 內(nèi)部函數(shù)可以引用外部函數(shù)的參數(shù)和變量
- 參數(shù)和變量不會被垃圾回收機制收回
所謂的垃圾回收機制是:找出不再使用的變量,然后釋放掉其占用的內(nèi)存妒貌,但是這個過程不是時時的资铡,因為其開銷比較大图仓,所以垃圾回收器會按照固定的時間間隔周期性的執(zhí)行.
function aa() {
a = 1;
}
aa();----執(zhí)行完以后,變量a就不存在了
二 閉包的好處
- 希望一個變量長期駐扎在內(nèi)存中
- 避免全局變量的污染
var res = (function() {
var count = 29;
return function add() {
count++;
console.log(count);
}
})();
res(); //30
res(); //31
res(); //32
res(); //33
三 自調(diào)用函數(shù)
- 自調(diào)用函數(shù)與閉包一塊使用
- 可以封閉變量的作用域
var btns = document.querySelectorAll("input");
for (var i = 0; i < btns.length; i++) {
//方法1
btns[i].index = i;
btns[i].onclick = function() {
console.log(this.index);
}
//方法2
(function(a) {
btns[a].onclick = function() {
alert(a);
}
})(i); //把變量i傳到內(nèi)部的函數(shù)中
}
四 創(chuàng)建構(gòu)造函數(shù)和創(chuàng)建對象
- 當(dāng)有很多的對象時需要創(chuàng)建一個類,即創(chuàng)建構(gòu)造函數(shù), 例如有很多的小球時
// 構(gòu)造函數(shù)
function Ball(x,y,r,speedX,speedY,color) {
this.r = r || random(20, 40);
this.x = x || random(this.r, canvasWidth - this.r);
this.y = y || random(this.r, canvasHeight - this.r);
this.speedX = speedX || random(1, 5);
this.speedY = speedY || random(5, 8);
//console.log(randomColor(1));
this.color = color || randomColor(2);
// 繪制
this.draw = function() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, Math.PI*2, false);
ctx.fillStyle = this.color;
ctx.fill();
}
// 運動
this.move = function () {
this.x += this.speedX;
this.y += this.speedY;
if (this.x < this.r || (this.x > canvasWidth - this.r)) {
this.speedX *= -1;
}
if (this.y < this.r || (this.y > canvasHeight - this.r)) {
this.speedY *= -1;
}
this.draw();
};
}
- 當(dāng)只有一個對象時,只需創(chuàng)建一個對象,例如只有一個飛機
// 飛機對象
var plane = {
w: 66,
h: 82,
x: canvasWidth / 2 - 33,
y: canvasHeight - 82,
draw: function () {
ctx.drawImage(loadedImgs.plane, 0, 0, this.w, this.h, this.x, this.y, this.w, this.h);
},
move: function () {
canvas.onmousemove = function (e) {
var ev = e || window.event;
var x = ev.clientX - canvas.offsetLeft;
var y = ev.clientY - canvas.offsetTop;
plane.x = x - plane.w / 2;
plane.y = y - plane.h / 2;
plane.draw();
};
}
};