new的原理解释:
new一个构造函数,如var eg = new Sprite(), new了之后的步骤是这样的
0.立即执行Sprite构造函数
1.在内存中开辟一块空间
2.创建一个新的空对象 如 var t = {}
3.把this指向这个空对象 this = t
4.把空对象的内部原型指向构造函数的原型对象 this._proto_ = eg.prototype
5.如果构造函数有返回值,立即把返回值给eg
6.如果没有返回值,就把构造函数里面的this作为返回值返回给eg,也就是如果没有返回值时,构造函数里面默认有这样一句代码 return this
一般我们把属性写在构造函数中,把方法写在构造函数的原型对象中
function Sprite(){//在构造函数中添加属性
this.name = "222"
// return this 默认有这行代码
}
Sprite.prototype.show = function (){//在构造函数原型对象中添加方法,主要是为了节省内存空间
console.log("jjjjg",this.name)
}
var s = new Sprite()//这样代码的内部执行过程就是对new的原理解释的6步
s.show()//s.show方法执行的时候,会首先去构造函数中找show()方法,如果有该方法就被调用,如果没有则去原型对象中找show()方法
案例代码
页面代码
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>面向对象的精灵图</title> <script src="./js/Sprite.js"></script> </head> <body> <div id="container"> <canvas id="cavsElem"> 你的浏览器太垃圾了,请升级你的浏览器 </canvas> </div> <button id="left">左</button> <button id="right">右</button> <button id="up">后</button> <button id="down">前</button> <script> (function (){ var canvas = document.getElementById("cavsElem") var ctx = canvas.getContext('2d') canvas.width = 600 canvas.height = 600 canvas.style.border = "1px solid red" var s = new Sprite({ x:200, y:200, w:80, h:130, fps:10, originW:40, originH:65, imgSrc:"imgs/DMMban.png" }) s.render(ctx) // 绑定按钮的点击事件 var left = document.getElementById("left") var right = document.getElementById("right") var up = document.getElementById("up") var down = document.getElementById("down") left.onclick = function (){ s.changeDir("1") } right.onclick = function (){ s.changeDir("2") } up.onclick = function (){ s.changeDir("3") } down.onclick = function (){ s.changeDir("0") } }()) </script> </body> </html>
js
function Sprite(option){ this._init(option) } Sprite.prototype = { _init:function (option){ this.x = option.x == 0 ? 0 : (option.x || 10) this.y = option.y == 0 ? 0 : (option.y || 10) this.w = option.w || 40//绘制到画布上的宽高 this.h = option.h || 65 this.fps = option.fps || 10 this.originW = option.originW || 40//截取的精灵图片的宽高 this.originH = option.originH || 65 this._dirIndex = 0 this._imgSrc = option.imgSrc || '' }, render:function (ctx){//把图片画到画布上去 var img = new Image() img.src = this._imgSrc var self = this img.onload = function (){ var frameIndex = 0 setInterval(function (){ ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height) ctx.drawImage( img, frameIndex * self.originW, self._dirIndex * self.originH, self.originW, self.originH, self.x, self.y, self.w, self.h ) frameIndex ++ frameIndex %= 4 },1000/self.fps) } }, changeDir:function (dir){ this._dirIndex = dir } }
图片
效果