javascript学习笔记(九)javascript中的原型(prototype)及原型链的继承方式


Posted in Javascript onApril 12, 2011

在使用面向对象编程时,对象间的继承关系自然少不了!而原型正是实现javascript继承的很重要的一种方法!
我们首先来看以下代码:

function person(name, age) { 
this.name = name; 
this.age = age; 
} 
person.prototype.getInfo = function() { 
alert("My name is "+this.name+", and I have "+this.age+" years old"); 
} 
var zhangchen = new person("zhangchen", 23); 
zhangchen.getInfo(); //output My name is zhangchen, and I have 23 years old;

从运行的结果我们可以看出,通过关键字new创建的zhangchen这个对象继承了person中通过原型定义的getInfo()方法。下面我们具体来看新建的zhangchen这个对象是如何继承person对象的属性和方法的。
原型:在使用 JavaScript 的面向对象编程中,原型对象是个核心概念。在 JavaScript 中对象是作为现有示例(即原型)对象的副本而创建的,该名称就来自于这一概念。此原型对象的任何属性和方法都将显示为从原型的构造函数创建的对象的属性和方法。可以说,这些对象从其原型继承了属性和方法。当创建zhangchen对象时:
var zhangchen = new company("zhangchen", 23);

zhangchen 所引用的对象将从它的原型继承属性和方法,对象 zhangchen 的原型来自构造函数(在这里是函数 person)的属性。

在 JavaScript 中,每个函数都有名为prototype的属性,用于引用原型对象。此原型对象又有名为constructor的属性,它反过来引用函数本身。这是一种循环引用, 下图更好地说明了这种循环关系。

javascript学习笔记(九)javascript中的原型(prototype)及原型链的继承方式

图1 循环关系

现在,通过new运算符用函数(上面示例中为 person)创建对象时,所获得的对象将继承 person.prototype 的属性。在上图,可以看到 person.prototype 对象有一个回指 person 函数的构造函数属性。这样,每个 person对象(从 person.prototype 继承而来)都有一个回指 person 函数的构造函数属性。

我们可以用以下代码来验证这种循环是否正确:

function person(name, age) { 
this.name = name; 
this.age = age; 
} person.prototype.getInfo = function() { 
alert("My name is "+this.name+", and I have "+this.age+" years old"); 
} 
var zhangchen = new person("zhangchen", 23); 
alert(zhangchen.constructor == person.prototype.constructor); //output true 
alert(zhangchen.constructor == person);// output true 
alert(person.prototype.isPrototypeOf(zhangchen)); //output true

以上代码中的对"isPrototypeOf()"方法的调用来自哪里呢?是来自person.prototype对象吗?不对,实际上,在 person.prototype 和 person 实例中还可以调用其他方法,比如 toString、toLocaleString 和 valueOf,但它们都不来自 person.prototype。而是来自于JavaScript 中的 Object.prototype ,它是所有原型的最终基础原型。(Object.prototype 的原型是 null。)

在以上例中,zhangchen.prototype 是对象。它是通过调用 Object 构造函数创建的(尽管它不可见)相当于执行子以下代码:

zhangchen.prototype = new Object();

因此,正如 person实例继承person.prototype 一样,zhangchen.prototype 继承 Object.prototype。这使得所有 zhangchen 实例也继承了 Object.prototype 的方法和属性。

原型链:每个 JavaScript 对象都继承一个原型链,而所有原型都终止于 Object.prototype。注意,这种继承是活动对象之间的继承。它不同于继承的常见概念,后者是指在声明类时类之间的发生的继承。因此,JavaScript 继承动态性更强。它使用简单算法实现这一点,如下所示:当您尝试访问对象的属性/方法时,JavaScript 将检查该属性/方法是否是在该对象中定义的。如果不是,则检查对象的原型。如果还不是,则检查该对象的原型的原型,如此继续,一直检查到 Object.prototype。下图说明了此解析过程:

javascript学习笔记(九)javascript中的原型(prototype)及原型链的继承方式
图2 toString()方法的解析过程

从以上解析过程中,如果在对象中定义了属性/方法 X,则该对象的原型中将隐藏同名的属性/方法。例如,通过在 person.prototype 中定义 toString 方法,可以改写 Object.prototype 的 toString 方法。

再看以下代码:

function person(name, age) { 
this.name = name; 
this.age = age; 
} 
person.prototype.getInfo = function() { 
alert("My name is "+this.name+", and I have "+this.age+" years old"); 
} 
var zhangchen = new person("zhangchen", 23); 
var luomi = new person("luomi", 23); 
zhangchen.getInfo(); // output My name is zhangchen, and I have 23 years old; 
luomi.getInfo(); // output My name is luomi, and I have 23 years old; 
luomi.getInfo = function() { 
alert("here can rewrite the function of getInfo!"); 
} 
luomi.getInfo(); //here can rewrite the function of getInfo! 
zhangchen.getInfo(); // output My name is zhangchen, and I have 23 years old;

从运行结果可以看到,虽然person的每个实例都继承了person.prototype中的方法,但是我们也可以在实例化的对象中重新定义原型对象中的方法,而且也不会影响到其它的实例!

以上是自己对原型及原型链继承方式的认识,参考( JavaScript: 使用面向对象的技术创建高级 Web 应用程序),希望大家共同讨论!

Javascript 相关文章推荐
JS 屏蔽按键效果与改变按键效果的示例代码
Dec 24 Javascript
JavaScript检查某个function是否是原生代码的方法
Aug 20 Javascript
JavaScript操作Cookie详解
Feb 28 Javascript
JavaScript如何实现在文本框(密码框)输入提示语
Dec 25 Javascript
Angular实现form自动布局
Jan 28 Javascript
javascript瀑布流布局实现方法详解
Feb 17 Javascript
JavaScript中访问id对象 属性的方式访问属性(实例代码)
Oct 28 Javascript
原生js编写基于面向对象的分页组件
Dec 05 Javascript
Node.js实现文件上传的示例
Jun 28 Javascript
VUE饿了么树形控件添加增删改功能的示例代码
Oct 17 Javascript
解决vuejs项目里css引用背景图片不能显示的问题
Sep 13 Javascript
如何在CocosCreator里画个炫酷的雷达图
Apr 16 Javascript
javascript 学习笔记(八)javascript对象
Apr 12 #Javascript
jQuery的初始化与对象构建之浅析
Apr 12 #Javascript
避免回车键导致的页面无意义刷新的解决方法
Apr 12 #Javascript
基于jquery实现的上传图片及图片大小验证、图片预览效果代码
Apr 12 #Javascript
javascript实现上传图片并预览的效果实现代码
Apr 11 #Javascript
window.dialogArguments 使用说明
Apr 11 #Javascript
30个最佳jQuery Lightbox效果插件分享
Apr 11 #Javascript
You might like
PHP实现视频文件上传完整实例
2014/08/28 PHP
利用ajax和PHP实现简单的流程管理
2017/03/23 PHP
Javascript开发之三数组对象实例介绍
2012/11/12 Javascript
JsRender实用入门教程
2014/10/31 Javascript
基于JavaScript实现树形下拉框
2016/08/10 Javascript
angular实现表单验证及提交功能
2017/02/01 Javascript
XMLHttpRequest对象_Ajax异步请求重点(推荐)
2017/09/28 Javascript
解决vue 路由变化页面数据不刷新的问题
2018/03/13 Javascript
vue.js通过路由实现经典的三栏布局实例代码
2018/07/08 Javascript
JS实现点击li标签弹出对应的索引功能【案例】
2019/02/18 Javascript
JQuery绑定事件四种实现方法解析
2020/12/02 jQuery
[02:26]2016国际邀请赛8月3日开战 中国军团出征西雅图
2016/08/02 DOTA
[43:57]LGD vs Mineski 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
[03:43]TI9战队采访——PSG.LGD
2019/08/22 DOTA
[59:00]DOTA2-DPC中国联赛 正赛 Ehome vs PSG.LGD BO3 第一场 3月7日
2021/03/11 DOTA
tensorflow saver 保存和恢复指定 tensor的实例讲解
2018/07/26 Python
ubuntu16.04制作vim和python3的开发环境
2018/09/23 Python
python打开windows应用程序的实例
2019/06/28 Python
python中Lambda表达式详解
2019/11/20 Python
python GUI库图形界面开发之PyQt5打开保存对话框QFileDialog详细使用方法与实例
2020/02/27 Python
Pycharm连接远程服务器过程图解
2020/04/30 Python
快速解释如何使用pandas的inplace参数的使用
2020/07/23 Python
Python3爬虫中关于中文分词的详解
2020/07/29 Python
Staples英国官方网站:办公用品一站式采购
2017/10/06 全球购物
20世纪40年代连衣裙和复古服装:The Seamstress Of Bloomsbury
2018/07/24 全球购物
采购助理岗位职责
2014/02/16 职场文书
优秀护士获奖感言
2014/02/20 职场文书
服务宗旨标语
2014/07/01 职场文书
乡镇挂职心得体会
2014/09/04 职场文书
出售房屋委托书范本
2014/09/24 职场文书
2015年国庆节慰问信
2015/03/23 职场文书
2015年小学财务工作总结
2015/07/20 职场文书
学生会副主席竞选稿
2015/11/19 职场文书
个人售房合同协议书
2016/03/21 职场文书
Python接口自动化之文件上传/下载接口详解
2022/04/05 Python
SQL Server使用CROSS APPLY与OUTER APPLY实现连接查询
2022/05/25 SQL Server