JavaScript:Class.method与Class.prototype.method
以下两个声明有什么区别?
Class.method = function () { /* code */ } Class.prototype.method = function () { /* code using this.values */ }
把第一个语句看作静态方法的声明,把第二个语句看作是一个实例方法的声明,可以吗?
是的,第一个函数与该构造函数的对象实例没有任何关系,您可以将其视为“静态方法” 。
在JavaScript中,函数是第一类对象,这意味着您可以像对待任何对象一样对待它们,在这种情况下,您只是将属性添加到函数对象中 。
第二个函数,在扩展构造函数原型的时候,它将会被所有使用new
关键字创build的对象实例所使用,并且该函数中的上下文( 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();
当创buildMyClass的多个实例时,在内存中仍然只有一个publicMethod实例,但在使用privilegedMethod的情况下,最终会创build大量实例,而staticMethod与对象实例没有关系。
这就是为什么原型可以节省内存。
另外,如果你改变了父对象的属性,那么孩子的相应属性没有被改变,它将被更新。
对于视觉学习者,在定义没有.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 + /