class.method/instance method
https://abdulapopoola.com/2013/03/30/static-and-instance-methods-in-javascript/
在阅读vue示例代码时,经常看到Vue.xx函数或者$vm.yy函数,不太清楚这两者之间有什么区别。
google以后发现实际上还是有本质的区别的。
我们知道javascript的继承模型和java,php等面向对象的编程语言有非常大的差别
js是一个弱典型的类型语言,class类并不是真正的class,实际上class就是本身也是object的construct functions.我们通过使用new constructor调用来创建新的对象,这实际上某种意义上模拟了OOP.但是请记住:js的继承模型和传统的javas, php是不同的!
首先有static property/instance property这个概率。所有对象属性(this.xx)都为public的,可以通过thisobj.xx直接访问。当然我们可以通过在constructor function(也就是class类定义)中增加var关键字使得相应属性变为private的,对于这种private类型的属性,我们必须通过定义accessors和setters才能够访问。
//Constructor var Person = function (name, age){ //private properties var priv = {}; //Public properties this.name = name; this.age = age; //Public methods this.sayHi = function(){ alert('hello'); } } // A static method; this method only // exists on the class and doesn't exist // on child objects Person.sayName = function() { alert("I am a Person object ;)"); }; // An instance method; // All Person objects will have this method Person.prototype.setName = function(nameIn) { this.name = nameIn; } // Tests var per = new Person('John Doe', 22); //Shows alert Person.sayName(); //TypeError: Object [object Object] has no method 'sayName' per.sayName() //Show alert per.sayHi(); //John Doe per.name; //22 per.age; per.setName('Jane Doe'); //Jane Doe per.name;
需要注意的是定义在类(构造函数)的属性上的static属性或者方法是不能在instance实例的上下文中访问的。但是java语言在这一点上就有所不同,在java中静态方法或者属性是可以在实例的上下文环境中访问的。这看起来非常奇怪,因为实例objects对象中并没有那个变量
这里我引用一下java的相关说明:
"
你也可以通过对象引用的模式来访问静态方法,比如:
myBike.numberOfBicycles
"
ES6中class method和instance method的对比
// es6 javascript code class Foo { bar() {...} static baz() {...} } const f = new Foo() f.bar() Foo.baz foo = {bar: 'baz'}; console.log(foo.bar); // logs "baz" // none-es6 javascript code foo = {}; console.log(foo.bar); // logs undefined function Foo(){} Foo.prototype = {bar: 'baz'}; f = new Foo(); console.log(f.bar); // logs "baz" because the object f doesn't have an attribute "bar" // so it checks the prototype f.bar = 'buzz'; console.log( f.bar ); // logs "buzz" because f has an attribute "bar" se Foo.talk = function () { alert('hello world!'); }; Foo.talk()
以Vue为例再看Vue.method/vueComponent.method
最后,我们来看Vuejs plugin中的几种用法,大家可以对照上面的所谓static和instance method来看:
MyPlugin.install = function (Vue, options) { // 1. add global method or property Vue.myGlobalMethod = function () { // some logic ... } // 2. add a global asset Vue.directive('my-directive', { bind (el, binding, vnode, oldVnode) { // some logic ... } ... }) // 3. inject some component options Vue.mixin({ created: function () { // some logic ... } ... }) // 4. add an instance method Vue.prototype.$myMethod = function (methodOptions) { // some logic ... } }