JavaScript:类。方法与Class.prototype.method

时间:2022-09-24 23:41:47

What is the difference between the following two declarations?

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

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

Is it okay to think of the first statement as a declaration of a static method, and the second statement as a declaration of an instance method?

可以将第一个语句看作静态方法的声明,将第二个语句看作实例方法的声明吗?

4 个解决方案

#1


643  

Yes, the first function has no relationship with an object instance of that constructor function, you can consider it like a 'static method'.

是的,第一个函数与构造函数的对象实例没有关系,您可以将它视为“静态方法”。

In JavaScript functions are first-class objects, that means you can treat them just like any object, in this case, you are only adding a property to the function object.

在JavaScript函数中是一级对象,这意味着您可以像对待任何对象一样对待它们,在本例中,您只是向函数对象添加了一个属性。

The second function, as you are extending the constructor function prototype, it will be available to all the object instances created with the new keyword, and the context within that function (the this keyword) will refer to the actual object instance where you call it.

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

Consider this example:

考虑一下这个例子:

// 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();

#2


16  

When you create more than one instance of MyClass , you will still only have only one instance of publicMethod in memory but in case of privilegedMethod you will end up creating lots of instances and staticMethod has no relationship with an object instance.

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

That's why prototypes save memory.

这就是为什么原型会保存内存。

Also, if you change the parent object's properties, is the child's corresponding property hasn't been changed, it'll be updated.

而且,如果您更改了父对象的属性,如果子对象的相应属性没有更改,那么它将被更新。

#3


7  

For visual learners, when defining the function without .prototype

对于视觉学习者来说,当定义函数时没有.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`  

With same code, if .prototype is added,

使用相同的代码,如果添加.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`

To make it clearer,

为了让它更清晰,

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

****Note for the example above, someInstance.method() won't be executed as,
ExampleClass.method() causes error & execution cannot continue.
But for the sake of illustration & easy understanding, I've kept this sequence.****

在上面的例子中,someInstance.method()不会被执行,ExampleClass.method()会导致错误和执行不能继续。但是为了便于理解和理解,我保留了这个序列。****。

Results generated from chrome developer console & JS Bin
Click on the jsbin link above to step through the code.
Toggle commented section with ctrl+/

从chrome开发人员控制台和JS Bin生成的结果单击上面的jsbin链接,以逐步完成代码。用ctrl+/切换注释部分

#4


0  

Yes, the first one is a static method also called class method, while the second one is an instance method.

是的,第一个是静态方法,也称为类方法,而第二个是实例方法。

Consider the following examples, to understand it in more detail.

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

In ES5

在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;
}

In the above code, isPerson is a static method, while sayHi is an instance method of Person.

在上面的代码中,isPerson是一个静态方法,sayHi是Person的实例方法。

Below, is how to create an object from Person constructor.

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

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

var aminu =新人(“aminu”,“Abubakar”);

Using the static method isPerson.

使用静态方法。

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

Person.isPerson(aminu);/ /将返回true

Using the instance method sayHi.

使用实例方法sayHi。

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

aminu.sayHi();//将返回“Hi Aminu”

In ES6

在ES6

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

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

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

Look at how static keyword was used to declare the static method isPerson.

看看静态关键字是如何用于声明静态方法isPerson的。

To create an object of Person class.

创建Person类的对象。

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

const aminu = new Person(“aminu”,“Abubakar”);

Using the static method isPerson.

使用静态方法。

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

Person.isPerson(aminu);/ /将返回true

Using the instance method sayHi.

使用实例方法sayHi。

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

aminu.sayHi();//将返回“Hi Aminu”

NOTE: Both examples are essentially the same, JavaScript remains a classless language. The class introduced in ES6 is primarily a syntactical sugar over the existing prototype-based inheritance model.

注意:这两个示例本质上都是相同的,JavaScript仍然是一种无类语言。在ES6中引入的类主要是对现有的基于原型的继承模型的语法补充。

#1


643  

Yes, the first function has no relationship with an object instance of that constructor function, you can consider it like a 'static method'.

是的,第一个函数与构造函数的对象实例没有关系,您可以将它视为“静态方法”。

In JavaScript functions are first-class objects, that means you can treat them just like any object, in this case, you are only adding a property to the function object.

在JavaScript函数中是一级对象,这意味着您可以像对待任何对象一样对待它们,在本例中,您只是向函数对象添加了一个属性。

The second function, as you are extending the constructor function prototype, it will be available to all the object instances created with the new keyword, and the context within that function (the this keyword) will refer to the actual object instance where you call it.

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

Consider this example:

考虑一下这个例子:

// 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();

#2


16  

When you create more than one instance of MyClass , you will still only have only one instance of publicMethod in memory but in case of privilegedMethod you will end up creating lots of instances and staticMethod has no relationship with an object instance.

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

That's why prototypes save memory.

这就是为什么原型会保存内存。

Also, if you change the parent object's properties, is the child's corresponding property hasn't been changed, it'll be updated.

而且,如果您更改了父对象的属性,如果子对象的相应属性没有更改,那么它将被更新。

#3


7  

For visual learners, when defining the function without .prototype

对于视觉学习者来说,当定义函数时没有.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`  

With same code, if .prototype is added,

使用相同的代码,如果添加.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`

To make it clearer,

为了让它更清晰,

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

****Note for the example above, someInstance.method() won't be executed as,
ExampleClass.method() causes error & execution cannot continue.
But for the sake of illustration & easy understanding, I've kept this sequence.****

在上面的例子中,someInstance.method()不会被执行,ExampleClass.method()会导致错误和执行不能继续。但是为了便于理解和理解,我保留了这个序列。****。

Results generated from chrome developer console & JS Bin
Click on the jsbin link above to step through the code.
Toggle commented section with ctrl+/

从chrome开发人员控制台和JS Bin生成的结果单击上面的jsbin链接,以逐步完成代码。用ctrl+/切换注释部分

#4


0  

Yes, the first one is a static method also called class method, while the second one is an instance method.

是的,第一个是静态方法,也称为类方法,而第二个是实例方法。

Consider the following examples, to understand it in more detail.

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

In ES5

在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;
}

In the above code, isPerson is a static method, while sayHi is an instance method of Person.

在上面的代码中,isPerson是一个静态方法,sayHi是Person的实例方法。

Below, is how to create an object from Person constructor.

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

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

var aminu =新人(“aminu”,“Abubakar”);

Using the static method isPerson.

使用静态方法。

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

Person.isPerson(aminu);/ /将返回true

Using the instance method sayHi.

使用实例方法sayHi。

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

aminu.sayHi();//将返回“Hi Aminu”

In ES6

在ES6

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

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

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

Look at how static keyword was used to declare the static method isPerson.

看看静态关键字是如何用于声明静态方法isPerson的。

To create an object of Person class.

创建Person类的对象。

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

const aminu = new Person(“aminu”,“Abubakar”);

Using the static method isPerson.

使用静态方法。

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

Person.isPerson(aminu);/ /将返回true

Using the instance method sayHi.

使用实例方法sayHi。

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

aminu.sayHi();//将返回“Hi Aminu”

NOTE: Both examples are essentially the same, JavaScript remains a classless language. The class introduced in ES6 is primarily a syntactical sugar over the existing prototype-based inheritance model.

注意:这两个示例本质上都是相同的,JavaScript仍然是一种无类语言。在ES6中引入的类主要是对现有的基于原型的继承模型的语法补充。