以下两个声明之间有什么区别?
Class.method = function () { /* code */ }
Class.prototype.method = function () { /* code using this.values */ }
是否可以将第一个语句视为静态方法的声明,将第二个语句视为实例方法的声明?
答案 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
是一种静态方法,而sayHi
是Person
的实例方法。
下面是如何从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 */ }
method()
是一个功能属性,已添加到另一个功能(此处为Class)。Class.method();
new Class()
)即可访问method()。因此,您可以将其称为静态方法。 B。原型方法(在所有实例中共享):
Class.prototype.method = function () { /* code using this.values */ }
method()
是将功能属性添加到另一个功能原型(此处为Class.prototype)。new Class()
C。类方法(每个实例都有自己的副本):
Class
function Class () {
this.method = function () { /* do something with the private members */};
}
是另一个函数(此处为Class)内部定义的方法。method()
Class.method();
)。new Class()
)。示例:
new Class()