JavaScript: Class.method vs. Class.prototype.method
以下两个声明有什么区别?
1 2 | Class.method = function () { /* code */ } Class.prototype.method = function () { /* code using this.values */ } |
可以将第一个语句看作静态方法的声明,将第二个语句看作实例方法的声明吗?
是的,第一个函数与该构造函数函数的对象实例没有关系,您可以将其视为"静态方法"。
在javascript中,函数是第一类对象,这意味着您可以像对待任何对象一样对待它们,在本例中,您只是向函数对象添加一个属性。
第二个函数在扩展构造函数函数原型时,它将可用于使用
考虑这个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // 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与对象实例没有任何关系。
这就是原型节省内存的原因。
此外,如果更改父对象的属性,则子对象的相应属性是否尚未更改,它将被更新。
对于视觉学习者,在定义没有
1 2 3 4 5 6 7 8 9 10 | 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` |
使用相同的代码,如果添加了
1 2 3 4 5 6 7 8 9 10 | 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` |
为了让它更清楚,
1 2 3 4 5 6 7 8 9 10 11 | 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()导致错误&无法继续执行。但是为了便于理解和说明,我保留了这个顺序。
是的,第一个是
考虑下面的例子,以便更详细地理解它。
在ES5中
1 2 3 4 5 6 7 8 9 10 11 12 | 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; } |
在上述代码中,
下面是如何从
采用静态方法
使用实例方法
在ES6中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } static isPerson(obj) { return obj.constructor === Person; } sayHi() { return `Hi ${this.firstName}`; } } |
看看如何使用
创建
采用静态方法
使用实例方法
注意:两个例子本质上是相同的,javascript仍然是一种无类语言。ES6中引入的