迟到的情人节,一块儿来玩儿一个属于程序员的俄罗斯方块吧!Tetris belongs to a programmerjavascript
github地址:https://github.com/EryouHao/t...java
在许多后端语言中,在基础部分,常常说面向对象很重要,好比在java中有类的概念,封装、继承、多态每每被称为面向对象的三个核心。简单来讲,封装就是为了更好的复用与继承。在JavaScript中,在ES6以前虽然没有类的概念,
但每每封装一些工具类,加强其复用性与便利性是一个不错的选择。git
曾有句经典的话:万事万物皆对象。在许多面向对象的讲授中,可能不少的都拿人作例子,一我的是一个对象,对象有一些属性(姓名、年龄、性别等等),对象有一些方法(吃饭、行走、说话),整我的类即一个类。不少状况下,一般new一我的类,即建立了一个具体的对象。那拿到面向对象编程来讲的话,这个对象能够是更为抽象的概念。程序员
在JavaScript中,也能够经过new
关键字来建立一个对象的实例。好比github
function Person(name,age) { this.name = name; this.age = age; } var zhangsan = new Person('张三', 18); console.log(zhangsan.name); // "张三" console.log(zhangsan.age); // 18
上面代码即经过new
关键字建立了一个对象,这个对象即有两个属性name
,age
。编程
一般,一次new,便建立一个实例对象,对象也确定会存在一些方法吧?对,咱们固然能够添加上方法,像下面这样:canvas
function Person(name, age) { this.name = name; this.age = age; this.say = function (msg) { console.log(msg); } } var zhangsan = new Person('张三', 18); zhangsan.say('hello'); // "hello"
这种方法虽然能实现,那因为经过构造函数生成的实例所拥有的的方法是指向函数的索引,若是存在多个实例的话,就会加大内存开销,因此,通常咱们定义到原型上。后端
function Person(name, age) { this.name = name; this.age = age; } Person.prototype = { constructor: Person, say: function (msg) { console.log(msg); }, _programme: function () { console.log('内部方法'); } } var zhangsan = new Person('张三', 18); zhangsan.say('hello'); // "hello"
这样当有多个实例时,指向的是一个函数索引。固然,也能够不经过原型,而经过指向外部函数也能够。属性通常都是每一个实例都有自身的一个副本,故直接定义。注意,若向上面所示,以重写原型对象的方式来挂载函数属性的话,将改变prototype
对象的constructor
属性。虽然这个属性通常没什么具体的做用,可是为了维持惯例,最好尽可能指向构造函数。浏览器
另外,面向对象的编程,很大程度上是利用上this
,经过this
就能够访问实例对象上的属相和原型上的方法。在模块化编程时更方便的调用。闭包
在编写复杂应用时,一般须要尽可能保持全局命名空间不被污染,自执行函数是其中一种。把代码封装在一个匿名函数中并马上自行调用,这样,该函数中的全部var
定义的变量都是局部的,并在函数返回时被销毁(前提是不属于闭包),下面是一个示例:
(function (window) { 'use strict'; function Score() { this.canvas = new Canvas('score', 100, 70); this.score = 0; this._init(); } Score.prototype = { constructor: Score, _init: function () { this._render(); }, _render: function () { this.canvas.drawText(this.score); }, addScore: function (value) { this.score += value; this._render(); return this.score; } }; window.Score = Score; })(window);
经过传入window
变量,使得window
由全局变量变为局部变量,这样能够更快的访问window,(另外能够在代码压缩时进行优化,未亲测)。
经过window.Score = Score;
在浏览器window对
象上,挂载一个属性,这样就能够被其余函数或模块进行调用,来建立实例,进行属性和方法的访问。好比上面的Canvas
即为挂载到window
对象上的属性。
利用面向对象的思想结合H5的Canvas就能够来编写一个简易的俄罗斯方块应用,一个应用中能够分为多个对象,好比一个Shape类(一个随机的俄罗斯方块),当落下一个方块,而且没有到顶部时,咱们就新建立一个(new
一个实例),里面能够有翻转函数(可被键盘事件控制调用),随机函数(生成实例时内部调用),游戏面板又能够根据方块的移动来更新绘制,分数能够根据消除的行进行更新绘制,这样经过对象来调用其属性方法,能够更合理地进行函数的模块划分与封装,使其应用代码更易维护与管理。
ps:哈哈,方块儿采用的Vue、Angular、React的图标,ps技术不高,还望见谅哇~