Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript:Class.method与Class.prototype.method_Javascript_Oop_Prototype Programming - Fatal编程技术网

JavaScript:Class.method与Class.prototype.method

JavaScript:Class.method与Class.prototype.method,javascript,oop,prototype-programming,Javascript,Oop,Prototype Programming,以下两种声明之间的区别是什么 Class.method = function () { /* code */ } Class.prototype.method = function () { /* code using this.values */ } < P> >将第一个语句看作静态方法的声明,将第二个语句作为实例方法的声明可以吗? < P>是的,第一个函数与它的对象实例没有关系,可以将其视为“静态方法”。 在JavaScript中,函数是对象,这意味着您可以像对待任何对象一样对待它们,在本

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

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

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

< P>是的,第一个函数与它的对象实例没有关系,可以将其视为“静态方法”。 在JavaScript中,函数是对象,这意味着您可以像对待任何对象一样对待它们,在本例中,您只需向函数对象添加一个属性

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

考虑这个例子:

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

当您创建多个MyClass实例时,内存中仍然只有一个publicMethod实例,但如果使用privilegedMethod,您将创建大量实例,并且staticMethod与对象实例没有关系

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


另外,如果您更改父对象的属性,如果子对象的相应属性未更改,则将更新该属性。

对于视觉学习者,在定义不带
的函数时。


对于相同的代码,如果添加了
.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开发者控制台生成的结果 单击上面的jsbin链接逐步浏览代码。

使用ctrl+/

切换注释部分是,第一个是
静态方法
,也称为
类方法
,而第二个是
实例方法

考虑以下示例,以便更详细地理解它

在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
是一个静态方法,
sayHi
Person
的一个实例方法

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

var aminu=新人(“aminu”、“Abubakar”)

使用静态方法
isPerson

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

使用实例方法
sayHi

aminu.sayHi();//将返回“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=新人(“aminu”、“Abubakar”)

使用静态方法
isPerson

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

使用实例方法
sayHi

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

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

a.静态方法:

  • method()
    这里是一个添加到另一个函数中的函数属性(这里是类)
  • 您可以通过类/函数名直接访问方法()<代码>类.方法()
  • 无需创建任何用于访问方法()的对象/实例(
    新类()
    )。因此,您可以将其称为静态方法。
  • B.原型方法(在所有实例中共享):

  • method()
    这里有一个函数属性添加到另一个函数protype(这里是Class.prototype)
  • 可以通过类名或通过对象/实例
    新建类()
    )直接访问
  • 附加优势-这种方法()定义将在内存中创建方法()的一个副本,并将共享所有对象/实例的
    类创建
  • C.Class方法(每个实例都有自己的副本):

  • method()
  • 不能通过类/函数名称直接访问方法()<代码>类.方法()
  • 需要为方法()访问创建对象/实例(
    新类()
  • 这种方法()定义将为使用构造函数(
    newclass()
    )创建的每个对象创建方法()的唯一副本
  • 新增优势-method()作用域的BCO它有权访问构造函数(此处为类)中声明的本地成员(也称为私有成员)
  • 例如:


    但是为什么Function.prototype.method==Function.method?@Raghavendra它不是t@Menda您的链接在“ES6”中已失效。您只描述了一个语法。这不是“ES2015”(请大家停止使用ES6,使用正确的术语ES2015)的方式。这只是另一种方式,在我看来是不正确的。@KarlMorrison Aminu没有写“方式”,你只是自己写的,并对它表示反对。关于ES6和ES2015,您的观点可能是公平的,但在conv中
    class Person {
       constructor(firstName, lastName) {
          this.firstName = firstName;
          this.lastName = lastName;
       }
    
       static isPerson(obj) {
          return obj.constructor === Person;
       }
    
       sayHi() {
          return `Hi ${this.firstName}`;
       }
    }
    
          Class.method = function () { /* code */ }
    
         Class.prototype.method = function () { /* code using this.values */ }
    
       function Class () {
          this.method = function () { /* do something with the private members */};
       }
    
        function Class() {
            var str = "Constructor method"; // private variable
            this.method = function () { console.log(str); };
        }
        Class.prototype.method = function() { console.log("Prototype method"); };
        Class.method = function() { console.log("Static method"); };
    
        new Class().method();     // Constructor method
        // Bcos Constructor method() has more priority over the Prototype method()
    
        // Bcos of the existence of the Constructor method(), the Prototype method 
        // will not be looked up. But you call it by explicity, if you want.
        // Using instance
        new Class().constructor.prototype.method(); // Prototype method
    
        // Using class name
        Class.prototype.method(); // Prototype method
    
        // Access the static method by class name
        Class.method();           // Static method