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

Do the different methods of creating classes in Javascript have names and what are they?

本文关键字:有名称 是什么 方法 Javascript 创建      更新时间:2023-09-26

我见过用这些不同的方式创建javascript类:


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


这些不同的方法类的声明有名字吗?它们是什么?我还遗漏了什么方法吗?

首先,让我们看看你问的那些实际上不是创建类的方法的事情。

如果你只需要一个有方法的对象,而不需要类,你可以创建一个对象字面值

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");
  };
}

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

无论何时输入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函数。

至于如何命名这两种将方法绑定到对象的方法,在构造函数内部声明的函数是特权方法,而用原型模式声明的函数称为公共方法

有人指出,Method 1是无效的js。方法1应该写成

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

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

方法2只是创建一个具有所需属性的对象字面值,根本不是一个"类"。

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

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