JavaScript:Class.method vs. Class.prototype.method

时间:2009-10-28 03:59:09

标签: javascript oop prototype-programming

以下两个声明之间有什么区别?

Class.method = function () { /* code */ }
Class.prototype.method = function () { /* code using this.values */ }

是否可以将第一个语句视为静态方法的声明,将第二个语句视为实例方法的声明?

5 个答案:

答案 0 :(得分:670)

是的,第一个函数与constructor function的对象实例没有关系,您可以将其视为'静态方法'

在JavaScript函数中有first-class个对象,这意味着您可以像对待任何对象一样处理它们,在这种情况下,您只是向函数对象添加属性

第二个函数,在扩展构造函数原型时,它将可用于使用new关键字创建的所有对象实例,以及该函数中的上下文(this关键字)将引用您调用它的实际对象实例。

考虑这个例子:

// constructor function
function MyClass () {
  var privateVariable; // private member only available within the constructor fn

  this.privilegedMethod = function () { // it can access private members
    //..
  };
}

// A 'static method', it's just like a normal function 
// it has no relation with any 'MyClass' object instance
MyClass.staticMethod = function () {};

MyClass.prototype.publicMethod = function () {
  // the 'this' keyword refers to the object instance
  // you can access only 'privileged' and 'public' members
};

var myObj = new MyClass(); // new object instance

myObj.publicMethod();
MyClass.staticMethod();

答案 1 :(得分:17)

当您创建MyClass的多个实例时,内存中仍然只有一个publicMethod实例,但是如果是privilegedMethod,则最终会创建大量实例,而staticMethod与对象实例没有关系。

这就是原型节省内存的原因。

此外,如果更改父对象的属性,是否未更改子对象的属性,则会更新它。

答案 2 :(得分:12)

对于视觉学习者,在没有 .prototype

的情况下定义功能时
ExampleClass = function(){};
ExampleClass.method = function(customString){
             console.log((customString !== undefined)? 
                          customString : 
                          "called from func def.");}
ExampleClass.method(); // >> output: `called from func def.`  

var someInstance = new ExampleClass();
someInstance.method('Called from instance');
    // >> error! `someInstance.method is not a function`  

使用相同的代码,如果添加 .prototype

ExampleClass.prototype.method = function(customString){
             console.log((customString !== undefined)? 
                          customString : 
                          "called from func def.");}
ExampleClass.method();  
      // > error! `ExampleClass.method is not a function.`  

var someInstance = new ExampleClass();
someInstance.method('Called from instance');
                 // > output: `Called from instance`

为了更清楚,

ExampleClass = function(){};
ExampleClass.directM = function(){}  //M for method
ExampleClass.prototype.protoM = function(){}

var instanceOfExample = new ExampleClass();

ExampleClass.directM();     ✓ works
instanceOfExample.directM();   x Error!

ExampleClass.protoM();     x Error!
instanceOfExample.protoM();  ✓ works

****请注意上面的示例,someInstance.method()不会被执行,因为, ExampleClass.method()导致错误&执行不能继续。
但是为了说明而且容易理解,我保留了这个序列。****

chrome developer console&生成的结果JS Bin
单击上面的jsbin链接以逐步执行代码 使用 ctrl + /

切换评论部分

答案 3 :(得分:6)

是的,第一个是static method,也称为class method,而第二个是instance method

请考虑以下示例,以便更详细地了解它。

在ES5中

function Person(firstName, lastName) {
   this.firstName = firstName;
   this.lastName = lastName;
}

Person.isPerson = function(obj) {
   return obj.constructor === Person;
}

Person.prototype.sayHi = function() {
   return "Hi " + this.firstName;
}

在上面的代码中,isPerson是一种静态方法,而sayHiPerson的实例方法。

下面是如何从Person构造函数创建对象。

var aminu = new Person("Aminu", "Abubakar");

使用静态方法isPerson

Person.isPerson(aminu); // will return true

使用实例方法sayHi

aminu.sayHi(); // will return "Hi Aminu"

在ES6中

class Person {
   constructor(firstName, lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
   }

   static isPerson(obj) {
      return obj.constructor === Person;
   }

   sayHi() {
      return `Hi ${this.firstName}`;
   }
}

查看static关键字如何用于声明静态方法isPerson

创建Person类的对象。

const aminu = new Person("Aminu", "Abubakar");

使用静态方法isPerson

Person.isPerson(aminu); // will return true

使用实例方法sayHi

aminu.sayHi(); // will return "Hi Aminu"

注意:两个示例基本相同,JavaScript仍然是无类语言。 ES6 中引入的class主要是现有基于原型的继承模型的语法糖。

答案 4 :(得分:1)

A。静态方法:

      Class.method = function () { /* code */ }
  1. method()是一个功能属性,已添加到另一个功能(此处为Class)。
  2. 可以通过类/函数名称直接访问method()。 Class.method();
  3. 不需要,无需创建任何对象/实例new Class())即可访问method()。因此,您可以将其称为静态方法。

B。原型方法(在所有实例中共享):

     Class.prototype.method = function () { /* code using this.values */ }
  1. method()是将功能属性添加到另一个功能原型(此处为Class.prototype)。
  2. 可以 通过类名或通过对象/实例({{1} })。
  3. 增加的优势-这种method()定义方式将在内存中仅创建 method()的一个副本,并将在所有共享 strong>从new Class()
  4. 创建的对象/实例的

C。类方法(每个实例都有自己的副本):

Class
  1. function Class () { this.method = function () { /* do something with the private members */}; } 是另一个函数(此处为Class)内部定义的方法。
  2. 不能通过类/函数名称直接访问method()。 method()
  3. 需要为method()访问创建一个对象/实例(Class.method();)。
  4. 这种method()定义方式将为使用构造函数创建的每个对象创建一个 method()的唯一副本new Class() )。
  5. 增加的优势-method()范围的Bcos有权访问在构造函数(此处为此处)中声明的 local 成员(也称为 private 成员)班级

示例:

new Class()