[03]-javaScript原型对象
引用: javaScript是一门基于原型的语言,它容许对象经过原型链引用另外一个对象来构建对象中的复杂性,JavaScript使用原型链这种机制来实现动态代理。当试图去引用某一个属性时,它会遍历整个原型链,直到最后的节点。JavaScript专家编程·P24java
1.1 原型对象说明
在JavaScript中除了基本数据类型外的其它数据都是对象类型,包括对象、函数、数组等,它们跟原型对象密不可分。编程
JavaScript语言中有一个很是重要的概念,叫作原型对象
,理解原型对象是进一步理解这门语言的基础,由于它是一门基于原型的语言,也由于全部的代码几乎都和原型对象有关,接下来咱们先了解下原型对象是什么。数组
原型对象浏览器
在上一篇文章JavaScript系列 [02]-javaScript对象探析中,咱们介绍了使用自定义构造函数建立对象的方式,在构造函数被建立出来的时候,系统会默认帮构造函数建立并关联一个Object类型的新对象,咱们称该对象就是这个构造函数的原型对象,构造函数的原型对象默认是一个空对象。函数
1.2 原型对象的性质
构造函数相关联的原型对象的成员(属性和方法),能够被使用该构造函数建立出来的对象访问,即以自定义构造函数方式建立出来的全部实例对象,都自动拥有和共享该构造函数原型对象中的全部属性和方法(想想为何空对象可使用toString方法,全部的数组均可以使用push等方法
)。this
代码示例spa
1 //01 声明构造函数Person 2 function Person(name) { 3 this.name = name; 4 } 5 //02 打印构造函数相关联的原型对象 6 console.log(Person.prototype); //Objec类型的空对象 7 //03 给构造函数原型对象添加方法 8 Person.prototype.showName = function () { 9 console.log(this.name); 10 }; 11 //04 使用构造函数建立实例对象 12 var p = new Person("文顶顶"); 13 p.showName(); //文顶顶 14 console.log(p);
代码说明prototype
☞ 上面的代码先提供了Person构造函数,该函数声明后,咱们经过Person.prototype访问其原型对象打印获得一个Object类型的空对象,说明全部的构造函数建立后默认拥有prototype属性,即构造函数默认有一个相关联的原型对象(Object类型空对象)。代理
☞ 随后咱们经过对象的动态特性给Person的原型对象添加了showName方法,经过打印结果能够验证构造函数的实例化对象(p)能够访问其原型对象上面的成员。调试
经过对代码和其运行结果分析,咱们不可贵出构造函数(Person)、原型对象(Person.prototype)、实例对象(p)之间的关系图,以下。
代码说明
① 实例对象p由Person构造函数实例化而来。
② Person构造函数能够经过prototype属性访问其原型对象。
③ 实例对象p能够经过proto属性访问其构造函数的原型对象(能够简称为p的原型对象,咱们在说原型对象的时候,应该先肯定主语是构造函数仍是实例对象,若是主语是构造函数,那么指的是构造函数.prototype,若是主语是实例对象,那么指的是建立该实例对象的构造函数相关联的原型对象,表示为实例对象.proto)。
④ 原型对象(Person.prototype)能够经过constructor(构造器)属性来访问其关联的构造函数,没法访问实例对象。
下面贴出上面代码更详细的原型结构关系图。
原型对象的访问
1 //获取原型对象的方式 2 //01 构造函数访问原型对象:构造函数.prototype 3 console.log(Person.prototype); 4 //02 构造函数的实例对象访问原型对象:实例对象.__proto__ 5 console.log(p.__proto__); 6 console.log(p.__proto__ == Person.prototype); 7 //03 经过Object.getPrototypeOf方法传递实例对象做为参数访问 8 console.log(Object.getPrototypeOf(p));
总结一下,原型对象的访问方式以下
① 构造函数.prototype ② 实例对象.__proto__ ③ Object.getPrototypeOf(实例对象)
原型对象总结
❐ 全部的对象都拥有
__proto__
属性,函数既拥有prototype属性又拥有__proto__
属性。
❐ 对象的__proto__
属性指向其构造函数相关联的原型对象(函数的__proto__属性也同样,指向其构造函数Function相关的原型对象,是一个空函数
)。
❐ 函数的prototype属性指向默认相关联的原型对象(函数和构造函数本质无差异)。
__proto__
是一个非标准属性,即ECMAScript中并不包含该属性,这只是某些浏览器为了方便开发人员开发和调试而提供的一个属性,不具有通用性。建议在调试的时候可使用该属性,但不能出如今正式的代码中,开发中可使用Object.getPrototypeOf方法来替代。
1.3 设置原型对象
所谓设置原型对象就是给构造函数的原型对象添加成员(属性和方法),具体的方式有两种
① 利用对象的动态特性设置
② 替换原有的原型对象
代码示例
1 //01 声明构造函数Person 2 function Person(name,age) { 3 this.name = name; 4 this.age = age || 18; 5 } 6 //02 给构造函数原型对象添加方法 7 //设置原型对象的第一种方法 8 Person.prototype.showName = function () { 9 console.log("姓名 "+this.name); 10 }; 11 Person.prototype.showAge = function () { 12 console.log("年龄 "+this.age); 13 }; 14 //04 使用构造函数建立实例对象 15 var p1 = new Person("文顶顶"); 16 p1.showName(); //姓名 文顶顶 17 p1.showAge(); //年龄 18 18 var p2 = new Person("章飞一绝",99); 19 p2.showName(); //姓名 章飞一绝 20 p2.showAge(); //年龄 99
像上面代码这样直接利用对象的动态特性来设置原型对象,在原有原型对象的基础上添加属性和方法很是简单,可是若是要添加的方法或属性比较多,那么冗余代码会比较多,这种状况推荐直接替换原有的原型对象。
1 //01 声明构造函数Person 2 function Person(name,age) { 3 this.name = name; 4 this.age = age || 18; 5 } 6 //02 给构造函数原型对象添加方法 7 //设置原型对象的第二种方法:直接替换原先的原型对象 8 Person.prototype = { 9 constructor:Person, 10 showName:function () { 11 console.log("姓名 "+this.name); 12 }, 13 showAge:function () { 14 console.log("年龄 "+this.age); 15 } 16 }; 17 //04 使用构造函数建立实例对象 18 var p = new Person("文顶顶"); 19 p.showName(); //姓名 文顶顶 20 p.showAge(); //年龄 18 21 console.log(p.constructor); //Person函数
注意
若是是直接替换原型对象,那么须要修正构造器属性,让constructor指向构造函数。说明
由于替换的时候实际上是用字面量的方式从新建立了新的对象,该对象做为Object构造函数的原型对象,内部没有constructor属性。这个时候若是要经过实例对象(好比p)的构造器属性判断其类型,那么会先在p身上找,没有则查找原型对象发现也没有,最终获得的Object.prototype身上的构造器属性,结果为Object 。
- Posted by 博客园·文顶顶 ~ 文顶顶的我的博客_花田半亩
- 联系做者 简书·文顶顶 新浪微博·文顶顶
- 原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | 文顶顶