javascript中prototype和_ _proto_ _两属性用法总结和心得
prototype和__proto__属性的用法和理解
prototype英文译名为原型,构造函数的prototype属性就是一个静态成员(只是构造函数的属性,普通函数调用没有任何作用),可以在所有实实例对象中共享数据。在此之前还是先了解一下原型对象:JavaScript 常被描述为一种基于原型的语言 (prototype-based language)——每个对象拥有一个原型对象,对象以其原型为模板、从原型继承方法和属性。原型对象也可能拥有原型,并从中继承方法和属性,一层一层、以此类推。这种关系常被称为原型链 (prototype chain),它解释了为何一个对象会拥有定义在其他对象中的属性和方法。1
例如:function MyClass(){age = 1;}; //构造函数(函数即是一种对象) 则此对象可通过MyClass.prototype访问原型对象。 当MyClass对象通过 new去创建新对象时候 ,var mc = new MyClass(); mc可通过__proto__属性访问原型对象,即构造函数创建的实例对象mc可通过mc.__proto__访问。
用下面一张图会理解的更明白:
(当我们访问对象的属性或者方法时,会先在对象自身中去找,如果有则直接使用,若果没有则会去原型对象中去找,如果有则使用)
由上图不难看出构造函数与其实例化对象都可以通过特定属性去访问同一个原型对象,既然可以访问原型对象,那原型对象中的属性自然可以得到。原型对象相当于一个共同区域,所有同一个类的实例都可以访问到同一个原型对象,我们可以把所有对象(包括实例化的)中的共同内容同一设置到原型对象中。
如果为构造函数增加一个getName方法,就可通过构造函数MyClass的prototype属性为其原型对象增加一个方法,(当然,也可以直接在构造函数内部直接添加,后面说不在内部添加的理由。)
MyClass.prototype.getName = function(){}; //向原型对象中添加getName函数。 此时实例化对象和构造函数都可以访问到此函数,即MyClass.getName(); mc.getName();
如果在MyClass中直接添加getName方法,那么如果实例化对象过多,构造函数每执行一次就会创建一个getName方法。即所以mc2.getName == mc.getName为false.
而直接通过prototype添加的mc2.getName == mc.getName为ture
此方式会增加效率。 ↩︎