在Javascript中创建类的不同方法是否有名称,它们是什么?

时间:2015-08-05 15:53:54

标签: javascript

我已经看到Javscript类创建了所有这些不同的方式:

function Thing() {

   method1: function() {

   },
   method2: function() {

   }   
}

方法1

var thing = {

   method1: function() {

   },
   method2: function() {

   }   
};

方法2

function Thing() {

}

Thing.prototype.method1 = function() {

}

Thing.prototype.method2 = function() {

}

方法3

var thing = (function(){
   var b={};

   b.method1 = function(){

   };

   b.method2 = function class2(){

   };

   return b;
}());

方法4

这些不同的方法声明类是否有名称,它们是什么?还有我错过任何方法吗?

2 个答案:

答案 0 :(得分:3)

首先,让我们看一下你问过哪些事实上不是制作课程的方法。

如果您只需要一个包含方法但没有类的对象,则可以创建对象文字

var myObject = {
  varname: value,
  varname: value,
  methodname: function() {
     // do something
  },
  methodname: function() {
     // do something
  }
};

这很少有用,但它会创建一个带有自己变量的实例,其中一些是函数。请注意,在JS中,属性和方法之间没有区别。方法只是function类型的属性。

使用var关键字在函数内创建的变量仅在函数内部可用。创建库的人通常以自执行函数的形式将整个代码包装在闭包中,以便代码末尾不再存在任何临时变量:

(function(){
  // code here
}());

现在要在JS中创建一个类,只需要创建一个构造函数。您可以使用this关键字在已创建的实例中存储属性。

function MyClass(param) {
  this.value = param;
}

var instance = new MyClass("example");

函数是存储在对象中的代码块。您可以将函数存储在变量中,就像其他任何东西一样,因此您也可以将函数存储在对象中。

function MyClass() {
  this.myMethod = function() {
    alert("hi");
  };
}

但由于您的类的所有实例都需要运行相同的代码,因此在构造函数中创建函数并不高效。这将为您创建的每个实例创建一个新的函数副本。因此,我们不是这样做,而是将函数存储在对象的原型中。

每当您输入say instance.someproperty时,JS引擎会查看instance以查看它是否具有名为someproperty的属性。如果它没有,它会尝试查看instance的原型,看看它是否具有该名称的属性。如果它没有,它会试着查看原型的原型......依此类推,直到它到达链的顶端。

因此,如果您将函数存储在MyClass.prototype.myMethod中,则可以使用instance.myMethod调用该函数,并且所有实例只共享该函数的一个副本。

function MyClass(param) {
  this.value = param;
}

MyClass.prototype.myMethod = function() {
  alert(this.value);
};

有一个很好的理由将函数放在构造函数中而不是使用原型链:制作伪私有变量和getter / setter函数。 See more here.

至于如何将这两种绑定方法命名为对象,在构造函数内声明的函数是特权方法,而使用原型模式声明的函数被称为<强>公共方法。您可以在一个类中使用它们。

答案 1 :(得分:1)

正如其他人所指出的,方法1无效js。方法1应该写成

function thing() {
    return {
        method1: function(){},
        method2: function(){}
    }
}

称为工厂函数,调用它(与任何普通函数一样)会生成具有指定属性的对象。但是,每个对象都有自己的拥有副本(这可能是不必要的),因此方法3将共享功能(方法,常量等)放入函数的原型中。通过调用函数创建的所有对象(应该使用new关键字与工厂函数进行对比调用)将可以访问附加到其构造函数原型的属性(但是所有对象都将共享一个指针相同的财产而不是他们自己的副本)。

方法2只是创建一个具有所需属性的对象文字,而不是一个&#39;类&#39;一点都不。

方法4也不是一个真正的课程&#39; (在任何意义上)它被称为模块模式,并使用词法闭包来封装通过返回的对象/函数显示公共API的功能。

如上所述,值得重申的是,这些都不是真正的类,ES 6 class关键字是方法3的语法糖。