理解JavaScript中的原型

学习JavaScript有一段时间了,感觉原型那块儿又有点混乱了,现在写个笔记整理一下思路。

什么是原型

每创建一个函数,这个函数都会自带一个属性prototype指向一个原型对象,最初这个原型对象只包含一个属性constructor,这是指向我们创建的那个函数的指针。也就是说函数和原型对象分别通过prototype和constructor这两个属性(指针)能找到对方。

我们可以通过fn.prototype.propertyName=value来给原型对象继续添加属性和方法。这些属性和方法区别于在函数中书写的实例属性和方法。为什么会有这种区别或者说这种区别是怎么做到的呢?来看看创建一个实例后发生了什么。以下面的代码来说明:

function Person(name,age){
    this.name=name,
    this.age=age;
}
Person.prototype.hobby = ["running","swimming","tennis"];
Person.prototype.country="China";
Person.prototype.showName=function(){alert(this.name);};

var person1 = new Person("anna",10);

这里创建了一个实例person1,我们知道通过new方法创建的实例,原来Person中的this会被新创建的实例即person1取代,也就是说通过这样的方式,我们为对象person1增加了属性name和age,这些是person1自己所拥有的属性,独立于其他Person的实例,叫做实例属性。
同时,每创建一个实例,这个实例会自带一个内部属性[prototype],它是一个指向构造函数的原型对象的引用。也就是说person1对象其实现在包括了这么三个属性:

person1={
   _proto_:Person.prototype,
   name:"anna",
   age:10
}

这个内部属性_proto_一般来说是不可以通过脚本来访问到的,那它有什么用呢?在进行属性标识符查找的时候会用到它。
引擎在读到某个对象的属性时,会首先查找实例属性中有没有这个属性,如果有则停止,没有则通过内部属性_proto_找到其关联的原型对象,看原型对象中有没有相应的属性。

实例属性和原型属性同名

这里需要注意,如果我们又为实例添加了一个和原型对象中同名的属性,或者说我们“重写”原型中的属性会发生什么。这得分属性是原始值类型还是引用类型。

  • 原始类型

    同名的实例属性会屏蔽掉原型对象中的同名属性,这里的屏蔽的意思是,这个属性是添加到实例属性上的,跟原型对象中的属性半毛钱关系没有,按照查找标识符的顺序会首先找到该实例属性,就不会再往上找原型中的了。它根本就不会“重写”原型对象中的属性,根本就是两个值,在内存中有两个空间。通过hasOwnProperty()可以看到已经成为自己的实例属性了:

person1.country="USA";  //重写属性
alert(person1.hasOwnProperty("country"));//true

可通过delete person1.country来删除实例属性,这样就又可以访问到原型对象中的属性了。

  • 引用类型

    引用类型也是一样的,当实例属性和原型中的属性同名的时候,就会屏蔽原型中的属性,可以通过delete(impletation.property)来删除实例属性以重新获取原型中的属性:

person1.hobby=['table tennis','singing'];
alert(person1.hasOwnProperty('hobby'));  //true

问题:原型对象showName方法中的this是实例对象?解释为谁调用this就是谁?
做了实验,的确是原型对象方法中的this是指向实例对象的:

Person.prototype.name = 'lily';
var p = new Person('anna', 10);
p.showName();  // 显示 anna

但如果实例没有自己的属性name,那么会沿着原型链查找这个属性,此时就是显示原型对象上的属性lily了。
由于时间关系先写到这儿,后面还会有补充。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值