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