javaScript系列 [03]-javaScript原型对象
[03]-javaScript原型对象
引用: javaScript是一门基于原型的语言,它允许对象通过原型链引用另一个对象来构建对象中的复杂性,JavaScript使用原型链这种机制来实现动态代理。当试图去引用某一个属性时,它会遍历整个原型链,直到最后的节点。JavaScript专家编程·P24
1.1 原型对象说明
在JavaScript中除了基本数据类型外的其它数据都是对象类型,包括对象、函数、数组等,它们跟原型对象密不可分。
JavaScript语言中有一个非常重要的概念,叫做原型对象
,理解原型对象是进一步理解这门语言的基础,因为它是一门基于原型的语言,也因为所有的代码几乎都和原型对象有关,接下来我们先了解下原型对象是什么。
原型对象
在上一篇文章JavaScript系列 [02]-javaScript对象探析中,我们介绍了使用自定义构造函数创建对象的方式,在构造函数被创建出来的时候,系统会默认帮构造函数创建并关联一个Object类型的新对象,我们称该对象就是这个构造函数的原型对象,构造函数的原型对象默认是一个空对象。
1.2 原型对象的性质
构造函数相关联的原型对象的成员(属性和方法),可以被使用该构造函数创建出来的对象访问,即以自定义构造函数方式创建出来的所有实例对象,都自动拥有和共享该构造函数原型对象中的所有属性和方法(想一想为什么空对象可以使用toString方法,所有的数组都可以使用push等方法
)。
代码示例
//01 声明构造函数Person
function Person(name) {
this.name = name;
}
//02 打印构造函数相关联的原型对象
console.log(Person.prototype); //Objec类型的空对象
//03 给构造函数原型对象添加方法
Person.prototype.showName = function () {
console.log(this.name);
};
//04 使用构造函数创建实例对象
var p = new Person("文顶顶");
p.showName(); //文顶顶
console.log(p);
代码说明
☞ 上面的代码先提供了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(构造器)属性来访问其关联的构造函数,无法访问实例对象。
下面贴出上面代码更详细的原型结构关系图。
原型对象的访问
//获取原型对象的方式
//01 构造函数访问原型对象:构造函数.prototype
console.log(Person.prototype);
//02 构造函数的实例对象访问原型对象:实例对象.__proto__
console.log(p.__proto__);
console.log(p.__proto__ == Person.prototype);
//03 通过Object.getPrototypeOf方法传递实例对象作为参数访问
console.log(Object.getPrototypeOf(p));
总结一下,原型对象的访问方式如下
① 构造函数.prototype
② 实例对象.__proto__
③ Object.getPrototypeOf(实例对象)
原型对象总结
❐ 所有的对象都拥有
__proto__
属性,函数既拥有prototype属性又拥有__proto__
属性。
❐ 对象的__proto__
属性指向其构造函数相关联的原型对象(函数的__proto__属性也一样,指向其构造函数Function相关的原型对象,是一个空函数
)。
❐ 函数的prototype属性指向默认相关联的原型对象(函数和构造函数本质无差别)。
__proto__
是一个非标准属性,即ECMAScript中并不包含该属性,这只是某些浏览器为了方便开发人员开发和调试而提供的一个属性,不具备通用性。建议在调试的时候可以使用该属性,但不能出现在正式的代码中,开发中可以使用Object.getPrototypeOf方法来替代。1.3 设置原型对象
所谓设置原型对象就是给构造函数的原型对象添加成员(属性和方法),具体的方式有两种
① 利用对象的动态特性设置
② 替换原有的原型对象
代码示例
//01 声明构造函数Person
function Person(name,age) {
this.name = name;
this.age = age || 18;
}
//02 给构造函数原型对象添加方法
//设置原型对象的第一种方法
Person.prototype.showName = function () {
console.log("姓名 "+this.name);
};
Person.prototype.showAge = function () {
console.log("年龄 "+this.age);
};
//04 使用构造函数创建实例对象
var p1 = new Person("文顶顶");
p1.showName(); //姓名 文顶顶
p1.showAge(); //年龄 18
var p2 = new Person("章飞一绝",99);
p2.showName(); //姓名 章飞一绝
p2.showAge(); //年龄 99
像上面代码这样直接利用对象的动态特性来设置原型对象,在原有原型对象的基础上添加属性和方法非常简单,但是如果要添加的方法或属性比较多,那么冗余代码会比较多,这种情况推荐直接替换原有的原型对象。
//01 声明构造函数Person
function Person(name,age) {
this.name = name;
this.age = age || 18;
}
//02 给构造函数原型对象添加方法
//设置原型对象的第二种方法:直接替换原先的原型对象
Person.prototype = {
constructor:Person,
showName:function () {
console.log("姓名 "+this.name);
},
showAge:function () {
console.log("年龄 "+this.age);
}
};
//04 使用构造函数创建实例对象
var p = new Person("文顶顶");
p.showName(); //姓名 文顶顶
p.showAge(); //年龄 18
console.log(p.constructor); //Person函数
注意
如果是直接替换原型对象,那么需要修正构造器属性,让constructor指向构造函数。说明
因为替换的时候其实是用字面量的方式重新创建了新的对象,该对象作为Object构造函数的原型对象,内部没有constructor属性。这个时候如果要通过实例对象(比如p)的构造器属性判断其类型,那么会先在p身上找,没有则查找原型对象发现也没有,最终得到的Object.prototype身上的构造器属性,结果为Object 。
- Posted by 博客园·文顶顶 ~ 文顶顶的个人博客_花田半亩
- 联系作者 简书·文顶顶 新浪微博·文顶顶
- 原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | 文顶顶
javaScript系列 [03]-javaScript原型对象的更多相关文章
- javaScript系列 [06]-javaScript和this
在javaScript系列 [01]-javaScript函数基础这篇文章中我已经简单介绍了JavaScript语言在函数使用中this的指向问题,虽然篇幅不长,但其实最重要的部分已经讲清楚了,这篇文 ...
- (一)我的Javascript系列:Javascript的面向对象旅程(上)
今宵酒醒何处,杨柳岸,晓风残月 导引 我的JavaScript系列文章是我自己对JavaScript语言的感悟所撰写的系列文章.现在还没有写完.目前一共出了下面的系列: (三)我的JavaScript ...
- javaScript系列 [04]-javaScript的原型链
[04]-javaScript的原型链 本文旨在花很少的篇幅讲清楚JavaScript语言中的原型链结构,很多朋友认为JavaScript中的原型链复杂难懂,其实不然,它们就像树上的一串猴子. 1.1 ...
- javaScript系列 [02]-javaScript对象探析
[02]-javaScript对象探析 题记:多年前,以非常偶然的方式关注了微信公众号“面向对象”,本以为这个公众号主要以分享面向对象编程的干货为主,不料其乃实实在在的猿圈相亲平台.通过查看公开资料, ...
- 深入理解Javascript中构造函数和原型对象的区别
在 Javascript中prototype属性的详解 这篇文章中,详细介绍了构造函数的缺点以及原型(prototype),原型链(prototype chain),构造函数(constructor) ...
- JavaScript学习笔记之原型对象
本文是学习<JavaScript高级程序设计>第六章的笔记. JS中,便于批量创建对象的三种模式: 1.工厂模式:用一个函数封装创建对象的细节,传入必要的参数,在函数内部new一个对象并返 ...
- 深入理解Javascript中构造函数和原型对象的区别(转存)
Object是构造函数,而Object.prototype是构造函数的原型对象.构造函数自身的属性和方法无法被共享,而原型对象的属性和方法可以被所有实例对象所共享. 首先,我们知道,构造函数是生成对象 ...
- JavaScript高级程序设计之原型对象
构造函数.原型对象.构造器是一体的关系,同时产生: 实例中的隐藏属性__proto__指向原型对象: 原型对象是这四种关系的纽带. 原型对象是动态的,不论在何处变化,实例中可以立即体现出来. var ...
- javaScript系列 [01]-javaScript函数基础
[01]-javaScript函数基础 1.1 函数的创建和结构 函数的定义:函数是JavaScript的基础模块单元,包含一组语句,用于代码复用.信息隐蔽和组合调用. 函数的创建:在javaScri ...
随机推荐
- 如何扩展Orchard
翻译自: http://msdn.microsoft.com/en-us/magazine/hh708754.aspx 动态类型系统 Content item是Orchard中的原子, 比如b ...
- Office 2010 word无法创建工作文件 请检查临时环境变量 的解决办法
Office 2010 word无法创建工作文件 请检查临时环境变量 的解决办法 http://hi.baidu.com/netshen/item/207fd935d452e0e9df2221c9 如 ...
- css3实现旋转表
如图所示: css部分: <style> #clock{width:100px; height:100px; border-radius:50%; border:4px solid bla ...
- HtmlTestRunner
1.一般生成报告时,会使用时间来作为报告名称的一部分,引入time这个第三方,使用以下方式格式化当前时间 下面运行最终结果:2019-03-29-14_29_18------>年-月-日-时-分 ...
- LCA算法解析-Tarjan&倍增&RMQ
原文链接http://www.cnblogs.com/zhouzhendong/p/7256007.html UPD(2018-5-13) : 细节修改以及使用了Latex代码,公式更加美观.改的过程 ...
- 实体转xml 并以string输出
<?xml version="1.0" encoding="utf-8"?><Root> <Header> <Mess ...
- Hive| 查询
Hive中执行SQL语句时,出现类似于“Display all 469 possibilities? (y or n)”的错误,根本原因是因为SQL语句中存在tab键导致,tab键在linux系统中是 ...
- 061 SparkStream数据接收原理
1.宏观 2.看英文解释过程 ------------------------------------------------------------------------------------- ...
- tp5参数绑定
关闭路由后的普通模式任然可以通过操作方法的参数绑定.控制器和空操作等特性实现url地址的简化 参数绑定(默认是按名称成对解析,): namespace app\index\Controller; cl ...
- Java常用API及Math类
一.API的概述 API——Application Programing Interface:应用程序编程接口,是java提供的一些预定义的函数: 目的:基于API实现程序的快速编写,只需了解其作用, ...