从俄罗斯方块来聊一聊面向对象

迟到的情人节,一块儿来玩儿一个属于程序员的俄罗斯方块吧!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技术不高,还望见谅哇~

clipboard.png

相关文章
相关标签/搜索