标签:
原型链模式
1、每一个对象(实例也是对象)都有一个天生自带的属性:__proto__,这个属性指向当前所属类的原型(prototype)
2、每一个函数(类也是函数)都有一个天生自带的属性:prototype(原型),并且这个属性存储的值是一个对象数据类型的数据,浏览器默认给这个属性开辟一个堆内存
在这个堆内存中存储了相关的属性和方法
1)其中constructor就是天生自带的一个属性,constructor等于当前的函数本身
2)__proto__:prototype对应的值也是一个对象数据类型的值,所以也天生自带__proto__这个属性
3)我们手动添加的属性和方法:这部分属于当前类的公有属性和方法
1 function Fn(num) {
2 this.a = num;
3 }
4 Fn.prototype.b = function () {
5
6 };
7 var f1 = new Fn(100);
8 var f2 = new Fn(200);
用画图的方式来表示如下:
Fn是f1,f2所属的类,
f1、f2是Fn的实例,所以f1.__proto__===Fn.prototype,f2.__proto__===Fn.prototype
首先找当前实例的私有属性,如果私有中存在,找的就是私有的,如果私有中不存在,默认根据__proto__找所属类prototype上公有的属性,公有中有的话就是公有的,如果公有也没有,则继续根据__proto__在往上一级找....一直到找到Object这个基类的prototype为止,如果基类上也没有,则代表当前实例没有这个属性,返回的结果是undefined
如下:
// console.log(f1.a); -->100
// console.log(f1.b); -->f1.__proto__.b
// console.log(f1.hasOwnProperty) -->f1.__proto__.__proto__.hasOwnProperty
// console.log(f1.zz); -->undefined
修改原型上公有属性和方法:
1.通过__proto__给原型上增加了一个属性
1 f1.__proto__.c = 300;//f1通过__proto__把原型上增加了一个c的属性,值是300
2 console.log(f2.c);//-->300
2.直接的通过Fn的prototype修改原型上的公有的属性和方法
1 Fn.prototype.b=1000;
2 console.log(f1.b); //-->1000
注:在所有IE浏览器中,浏览器为了保护类的原型,屏蔽了__proto__的使用,console.log(f1.__proto__.b);//在IE下-->无法获取属性“b”的值: 对象为 null 或未定义。
如果想往类的原型上增加(修改)属性和方法,兼容所有浏览器的只有Fn.prototype这种方式。
标签:
原文地址:http://www.cnblogs.com/cataway/p/4878886.html