一 闭包的特点
- 函数嵌套函数
- 内部函数可以引用外部函数的参数和变量
- 参数和变量不会被垃圾回收机制收回
所谓的垃圾回收机制是:找出不再使用的变量,然后释放掉其占用的内存,但是这个过程不是时时的,因为其开销比较大,所以垃圾回收器会按照固定的时间间隔周期性的执行.
function aa() {
a = 1;
}
aa();----执行完以后,变量a就不存在了
二 闭包的好处
- 希望一个变量长期驻扎在内存中
- 避免全局变量的污染
var res = (function() {
var count = 29;
return function add() {
count++;
console.log(count);
}
})();
res(); //30
res(); //31
res(); //32
res(); //33
三 自调用函数
- 自调用函数与闭包一块使用
- 可以封闭变量的作用域
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传到内部的函数中
}
四 创建构造函数和创建对象
- 当有很多的对象时需要创建一个类,即创建构造函数, 例如有很多的小球时
// 构造函数
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();
};
}
- 当只有一个对象时,只需创建一个对象,例如只有一个飞机
// 飞机对象
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();
};
}
};