js原型小结

来源:互联网 发布:2016季后赛数据 编辑:程序博客网 时间:2024/05/17 20:28



下面的代码从原型上来看存在上面关系?


function ftn() {}var fn = new ftn();


一、第一部分

下图


222


ftn中有一个prototype属性,它指向一个prototype对象(这个prototype===Object.prototype.constructor)。而 prototype对象中的constructor指向function本身

如: ftn.prototype  这里访问prototype属性,得到的是一个prototype对象。 ftn.prototype.constructor  === function ftn() {} 这个function方法

这两种关系看图就很容易明白,但是 上图的one缺有点小复杂,one代表的是function创建的对象,也就是上边的fn。从网上某个大神博客里摘除一段话

按照《悟透javascript》书中说的,new形式创建对象的过程实际上可以分为三步:
第一步是建立一个新对象(叫A吧);

第二步将该对象(A)内置的原型对象设置为构造函数(就是Person)prototype 属性引用的那个原型对象;

第三步就是将该对象(A)作为this 参数调用构造函数(就是Person),完成成员设置等初始化工作。

其中第二步中出现了一个新名词就是内置的原型对象,注意这个新名词跟prototype对象不是一回事,为了区别我叫它inobj,inobj就指向了函数Person的prototype对象。在person的prototype对象中出现的任何属性或者函数都可以在one对象中直接使用,这个就是javascript中的原型继承了。

也就是说one中的 inobj(firefox里面叫__proto__)指向的是prototype对象。完成第二步,就可以通过one来调用任何prototype上的属性/方法,完成第三步就可以调用function的成员属性/方法

看个例子

function ftn() {      this .name = 'stray';       this .getName = function () {             alert( this.name);       }}ftn.prototype.age = '111';ftn.prototype.getAge = function() {       alert( this.age);}var fn = new ftn();fn.getAge();

想使用ftn的成员属性this.name ,成员方法this.getName() 以及ftn.prototype.age ftn.prototype.getAge(),那么我们只能通过创建对象var fn = new ftn(); fn可以访问prototype中的任何属性
二、第二部分 继承
下图


上边的图用代码表示就是

function Person() {      this .name = 'stray';       this.getName = function () {             alert(this.name);       }}function SubPer() {}SubPer.prototype = new Person();

Suber.prototype指向的prototype对象被替换成了上图的father也就是new Person这个对象,而从第一部分可以知道这个father对象可以调用Person的成员属性/方法,以及Person.prototype原型上的所有属性/方法,那么我们通过创建
var son = new SubPer() 可以使用Person的成员属性/方法,以及Person原型上的属性/方法

好了,原型基本理论正如上边说的那样,下面针对第二部分内容进行一些更改
问题:SubPer.prototype.constructor 指向的是那个?
没错,就是Person.prototype原型上的那个constructor,所以,我的修改啊。SuPer虽然继承了Person但是构造函数还是得改回SubPer,如下一行代码

SubPer.prototype.constructor = SubPer;

这里值得注意的一点就是:应该是SubPer.prototype = new Person(); SubPer.prototype.constructor = SubPer;
更改原型上的属性/方法后,不会对Persion.prototype 原型属性/方法造成影响,所以
alert(Person.prototype.constructor); //输出的还是Person

但是如果是下面这种情况呢?

function Person() {      this .name = 'stray';       this.getName = function () {             alert(this.name);       }}Person.prototype.getName = function() {       alert('Person');}function SubPer() {}SubPer.prototype = Person.prototype;SubPer.prototype.constructor = SubPer;SubPer.prototype.getName = function() { //①       alert('SubPer');}Person.prototype.getName();alert(Person.prototype.constructor);

注意加红色的部分,这里SubPer.prototype不再指向上图的father了,直接指向Person的prototype对象,这样做的结果是,SubPer只能继承Person.prototype上的属性/方法 而Person里面的成员属性/方法this.name,this.getName 是无法继承,
当更改了SubPer.prototype上的属性/方法(①) 那么Person.prototype也发生了更改

我们可以对比下2种方式,更加具体情况,选择使用




0 0