(function(global){}(this),构造函数和Javascript中的类有什么区别?

时间:2017-11-28 20:13:51

标签: javascript oop

我目前有三种方法知道如何制作类和对象。

方法1(这个可怕的事情):

;(function(global) {
  let module = global.player1 = {};
  module.x = 0;
  module.y = 0;
  module.tick = function() { /* Do stuff */ }
  module.show = function(g) {
    g.fillRect(module.x, module.y, 16, 16);
  }
})(this);

方法2(ES6类):

class CPlayer {
  constructor() {
    this.x = 16;
    this.y = 0;
  }
}
CPlayer.prototype.tick = function() { /* Do stuff */ }
CPlayer.prototype.show = function(g) {
    g.fillRect(this.x, this.y, 16, 16);  
}
let player2 = new CPlayer();

方法3(构造函数):

function FPlayer() {
  this.x = 32;
  this.y = 0;
}
FPlayer.prototype.tick = function() { /* Do stuff */ }
FPlayer.prototype.show = function(g) {
  g.fillRect(this.x, this.y, 16, 16);  
}
let player3 = new FPlayer();

三者之间有什么区别,哪一个最有效/最实用?特别是第一种方法?

1 个答案:

答案 0 :(得分:2)

方法1不是类,也不是对象,而是一个模块 - 这个方法允许您将一些代码封装在一个在当前执行环境中立即执行的函数中。由于您在调用时传递this,因此无论您当前的范围是其上下文(并且可以从类声明中调用,例如,作为一种类型混入。

方法2是ES6中新提供的,如您的问题中所述。一些开发人员对此不以为然,因为它引起了混乱。例如,请参见:https://medium.com/@rajaraodv/is-class-in-es6-the-new-bad-part-6c4e6fe1ee65。这样做的基本优点是它为我们提供了一些语法糖,而缺点是它使得它看起来像JavaScript 实际上有类,而它没有(并且在你的问题本身中再次提到,它依赖于原型继承)。

方法3是创建对象的“经典”方法。依赖于JavaScript作用域,闭包和上下文的工作方式,我们得到了一个可以被称为类构造函数的函数,它确实可以很好地逼近它。就个人而言,这仍然是我首选的方法 - 所列出的三种方法在效率上没有实际差异,但这种方法是最古老的,因此也是最普遍的,并且可读。出于这个原因,它得到了我的投票。