1.对prototype的理解
function F(){};
f1=new F();
f2=new F();
以上的代码,F()是一个构造函数,f1和f2是有这个构造函数产生的实例对象。</pre>
prototype是构造函数的一个属性,他的值就是由这个构造函数构造出来的对象 (如f1和f2) 的原型对象.(换句话说,prototype既是构造函数的属性,也是f1,f2的原型对象)。f1._ proto _= F.prototype
构建对象中有一种模式叫做原型模式,意思是将对象实例所不可共享的属性及方法定义在构造函数中,而将可共享的属性及方法放在原型对象中,也就是prototype指向的对象中。p1和p2对象实例的内存空间里面各有一份name和age,但是它们却共享一份sayName方法,意思是它们调用的sayName方法是同一个。所以prototype的好处之一就是提高了代码的复用性,减少内存消耗。
在了解原型对象的同时我们还有一个小知识要明白:
每当代码读取一个对象属性的时候会执行一次搜索,搜索目标是给定名字的属性,搜索路径为:
对象实例本身---->原型对象---->对象的父类对象---->父类对象原型...---->原型链末端
2.prototype的注意点
-
不可变性
尽管prototype是共享的,但不能通过对象实例重写原型中的值,但是可以由对象统一改。通俗一点:只能爸爸统一改,不能儿子改。(这也和类型有关系,孩子不能改变基本类型的值,但是可以改变对象,比如改变数组内容)
-
基本类型
function person(){
Person.prototype={ num:0}
}
var p1=new Person();
var p2=new Person();
P1.num++;
p2.num // 0 (对象实例不能改变基本类型)
-
非基本类型
Function person(){
Person.prototype={ num:[1,2,3] };
}
var p1=new person();var p2=new person();
P1.num[2]=8;
P2.num // [1,2,8] (对象实例不能改变基本类型)
-
-
同名覆盖性
如果我们在实例中添加了一个与原型属性同名的属性,那么该属性会创建到对象实例中并且会覆盖掉原型中的相应属性。</pre>
-
使用对象字面量创建原型方法,会切断之前的链而重写原型链
总结:
- prototype的用法:构造函数模型用于定义实例的属性,二原型模型用于定义方法和共享属性(在ES5中是这样,在ES6中有class关键字代替)
3.prototype和 _ proto _的区别
__ proto __ 是某个实例对象的属性,它指向这个对象的原型对象。而prototype则是构造函数的属性。从上面的例子分析,f1. __ proto 和f2. _ proto__就等同于F.prototype。
图片1.png4.原型链
每个对象都有自己的原型对象,那一层层地,就形成了原型链。原型链的最上端,就是Object.prototype(注意这里的Object是一个构造函数啊),它没有原型对象(为null)。原型链后面的对象,能够使用前面的属性和方法(假如没有覆盖掉的话)。因此,有着相同原型对象的两个对象,就可以使用与原型对象相同的方法和属性了,这也是使用prototype的好处了。
5.constructor
prototype对象有一个constructor属性,F.prototype.constructor的值就是F本身。用文字描述,一个函数对象的原型对象的constructor属性指向这个函数本身。(ES6中class的constructor可能就是这样封装的)</pre>
利用这一点,我们可以进行判断一个对象是否由某个构造函数产生的。(利用这个例子来理解constructor属性吧)
function A(){};
var a = new A();
console.log(a.constructor===A) //true
分析一下以上的代码,a原本是没有constructor这个属性的,但是它的原型对象有,所以它“继承”了下来,自己也能使用这个属性。即a.constructor,其实也等于a.proto.constructor和A.prototype.constructor,而A.prototype.constructor的值,就是A(同理,A.constructor=A.proto.constructer=Object.prototype.constructor=Object本身,即 方法A的构造函数是Object),因此返回true了。
关于constructor的作用还有很多,这里不详述了
5.prototype的作用
定义在原型对象上的所有属性和方法,都能被派生对象继承。这就是JavaScript继承机制的基本设计。prototype对象的作用,就是定义所有实例对象共享的属性和方法,所以它也被称为实例对象的原型,而实例对象可以视作从prototype对象衍生出来的。
网友评论