從俄羅斯方塊來聊一聊面向對象

遲到的情人節,一塊兒來玩兒一個屬於程序員的俄羅斯方塊吧!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

相關文章
相關標籤/搜索