Javascript 原型和继承(Prototypes and Inheritance)


Posted in Javascript onApril 01, 2009

JavaScript 对象从一个原形对象(prototype object) 继承属性。所有对象都有原型;原型的所有属性看上去就像使用它作为原型的那些对象的属性一样。简单的说就是:所有对象都从他的原型继承属性
(each object inherits properties from its prototype).

对象的 prototype 通过它的 constructor function 来定义。JavaScript 里所有的 function 都有一个 prototype 属性。这个属性开始是空的,接下来你给他添加的任何属性都会被 constructor 创建的对象所拥有。

prototype 对象和 constructor 相关联。这意味着 prototype 可以作为放置方法以及其他常量的理想场所。原型中的属性不会被复制到新创建的对象中去,他们的属性看上去就像对象的属性一样。这意味着,使用原型能够大幅度的减少多个同类对象占用的内存。

每一个 class 都只有一个 prototype object, 附带一套属性。但我们在运行时可能会创建多个类的实例。那么如果发生对原型的属性的读写会发生什么情况?
当你读一个属性的时候,JavaScript 首先尝试去查找对象本身是否有这个属性,如果没有,接着去查找原型里面是否有。有的话就返回结果。
而当你写原型的属性的时候,因为多个对象共享原型,显然是不能直接在原型上进行写操作的。这个时候实际上 JavaScript 会在对象上创建一个同名的属性,然后把值写到里面。当你下次读这个属性的时候,JavaScript 一下子就在对象的属性里查找到了,那么就不需要去原型里查找了。这个时候,我们说“对象的属性掩盖或隐藏了原型的属性”。(shadows or hides) 。

从上面讨论看出,其实我们在设计类的时候,只要掌握一个原则:在原型里仅定义一些方法(方法一般是不会变的),常数,常量等。做到这一点就不容易混淆了。
例子:

Javascript 原型和继承(Prototypes and Inheritance)// Define a constructor method for our class.
Javascript 原型和继承(Prototypes and Inheritance)// Use it to initialize properties that will be different for
Javascript 原型和继承(Prototypes and Inheritance)// each individual Circle object.
Javascript 原型和继承(Prototypes and Inheritance)functionCircle(x, y, r)
Javascript 原型和继承(Prototypes and Inheritance){
Javascript 原型和继承(Prototypes and Inheritance)    this.x = x;  // The X-coordinate of the center of the circle
Javascript 原型和继承(Prototypes and Inheritance)
this.y = y;  // The Y-coordinate of the center of the circle
Javascript 原型和继承(Prototypes and Inheritance)
this.r = r;  // The radius of the circle
Javascript 原型和继承(Prototypes and Inheritance)}
Javascript 原型和继承(Prototypes and Inheritance)
Javascript 原型和继承(Prototypes and Inheritance)
Javascript 原型和继承(Prototypes and Inheritance)// Create and discard an initial Circle object.
Javascript 原型和继承(Prototypes and Inheritance)// This forces the prototype object to be created in JavaScript 1.1.
Javascript 原型和继承(Prototypes and Inheritance)new Circle(0,0,0);
Javascript 原型和继承(Prototypes and Inheritance)
Javascript 原型和继承(Prototypes and Inheritance)
Javascript 原型和继承(Prototypes and Inheritance)// Define a constant: a property that will be shared by
Javascript 原型和继承(Prototypes and Inheritance)// all circle objects. Actually, we could just use Math.PI,
Javascript 原型和继承(Prototypes and Inheritance)// but we do it this way for the sake of instruction.
Javascript 原型和继承(Prototypes and Inheritance)Circle.prototype.pi =
3.14159;
Javascript 原型和继承(Prototypes and Inheritance)
Javascript 原型和继承(Prototypes and Inheritance)
Javascript 原型和继承(Prototypes and Inheritance)// Define a method to compute the circumference of the circle.
Javascript 原型和继承(Prototypes and Inheritance)// First declare a function, then assign it to a prototype property.
Javascript 原型和继承(Prototypes and Inheritance)// Note the use of the constant defined above.
Javascript 原型和继承(Prototypes and Inheritance)function Circle_circumference(  ) { return
2
*
this.pi *
this.r; }
Javascript 原型和继承(Prototypes and Inheritance)Circle.prototype.circumference =Circle_circumference;
Javascript 原型和继承(Prototypes and Inheritance)
Javascript 原型和继承(Prototypes and Inheritance)
Javascript 原型和继承(Prototypes and Inheritance)// Define another method. This time we use a function literal to define
Javascript 原型和继承(Prototypes and Inheritance)// the function and assign it to a prototype property all in one step.
Javascript 原型和继承(Prototypes and Inheritance)Circle.prototype.area =
function(  ) { return
this.pi *
this.r *
this.r; }
Javascript 原型和继承(Prototypes and Inheritance)
Javascript 原型和继承(Prototypes and Inheritance)
Javascript 原型和继承(Prototypes and Inheritance)// The Circle class is defined.
Javascript 原型和继承(Prototypes and Inheritance)// Now we can create an instance and invoke its methods.
Javascript 原型和继承(Prototypes and Inheritance)var c =
new Circle(0.0, 0.0, 1.0);
Javascript 原型和继承(Prototypes and Inheritance)var a =c.area(  );
Javascript 原型和继承(Prototypes and Inheritance)var p = c.circumference(  );

内置的类的 prototype.

不光是用户自定义的类可以有 prototype. 系统内置的类比如 String, Date 也都有的。而且你可以向他们添加新的方法,属性等。
下面这段代码就对所有的 String 对象添加了一个有用的函数:

Javascript 原型和继承(Prototypes and Inheritance)// Returns true if the last character is c
Javascript 原型和继承(Prototypes and Inheritance)String.prototype.endsWith =
function(c) {
Javascript 原型和继承(Prototypes and Inheritance)    return (c ==
this.charAt(this.length-1))
Javascript 原型和继承(Prototypes and Inheritance)}

然后我们就可以类似这样的来调用了:

Javascript 原型和继承(Prototypes and Inheritance)var message =
"hello world";
Javascript 原型和继承(Prototypes and Inheritance)message.endsWith('h')  // Returns false
Javascript 原型和继承(Prototypes and Inheritance)message.endsWith('d')  // Returns true

Javascript 相关文章推荐
Firefox getBoxObjectFor getBoundingClientRect联系
Oct 26 Javascript
Javascript 面向对象 对象(Object)
May 13 Javascript
javascript 从if else 到 switch case 再到抽象
Jul 17 Javascript
推荐20家国外的脚本下载网站
Apr 28 Javascript
IE关闭时判断及AJAX注销案例学习
Feb 18 Javascript
JS 添加千分位与去掉千分位的示例
Jul 11 Javascript
简介JavaScript中的push()方法的使用
Jun 09 Javascript
js模糊查询实例分享
Dec 26 Javascript
如何选择适合你的JavaScript框架
Nov 20 Javascript
从setTimeout看js函数执行过程
Dec 19 Javascript
基于three.js实现的3D粒子动效实例代码
Apr 09 Javascript
bootstrap tooltips在 angularJS中的使用方法
Apr 10 Javascript
说说掌握JavaScript语言的思想前提想学习js的朋友可以看看
Apr 01 #Javascript
setTimeout 不断吐食CPU的问题分析
Apr 01 #Javascript
js Flash插入函数免激活代码
Mar 31 #Javascript
响应鼠标变换表格背景或者颜色的代码
Mar 30 #Javascript
用JavaScript实现单继承和多继承的简单方法
Mar 29 #Javascript
javascript 极速 隐藏/显示万行表格列只需 60毫秒
Mar 28 #Javascript
一个tab标签切换效果代码
Mar 27 #Javascript
You might like
php定时计划任务与fsockopen持续进程实例
2014/05/23 PHP
Win2003+apache+PHP+SqlServer2008 配置生产环境
2014/07/29 PHP
php利用scws实现mysql全文搜索功能的方法
2014/12/25 PHP
php基于curl实现的股票信息查询类实例
2016/11/11 PHP
Laravel框架分页实现方法分析
2018/06/12 PHP
PDO实现学生管理系统
2020/03/21 PHP
ajax 缓存 问题 requestheader
2010/08/01 Javascript
javascript面向对象包装类Class封装类库剖析
2013/01/24 Javascript
JS下拉框内容左右移动效果的具体实现
2013/07/10 Javascript
文本域光标操作的jQuery扩展分享
2014/03/10 Javascript
node爬取微博的数据的简单封装库nodeweibo使用指南
2015/01/02 Javascript
node.js中格式化数字增加千位符的几种方法
2015/07/03 Javascript
学习JavaScript设计模式之观察者模式
2020/04/22 Javascript
关于JS中setTimeout()无法调用带参函数问题的解决方法
2016/06/21 Javascript
JS清除字符串中重复值的实现方法
2016/08/03 Javascript
jQuery progressbar通过Ajax请求实现后台进度实时功能
2016/10/11 Javascript
快速使用node.js进行web开发详解
2017/04/26 Javascript
微信小程序下拉加载和上拉刷新两种实现方法详解
2019/09/05 Javascript
Vue表单控件数据绑定方法详解
2020/02/05 Javascript
Vue实现手机扫描二维码预览页面效果
2020/05/28 Javascript
Nuxt.js 静态资源和打包的操作
2020/11/06 Javascript
[01:23:24]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Elephant BO3 第三场 2月7日
2021/03/11 DOTA
Flask SQLAlchemy一对一,一对多的使用方法实践
2013/02/10 Python
Django后端按照日期查询的方法教程
2021/02/28 Python
Nike香港官网:Nike HK
2019/03/23 全球购物
澳大利亚波希米亚风时尚品牌:Tree of Life
2019/09/15 全球购物
MUGLER官方网站:蒂埃里·穆勒香水
2019/11/26 全球购物
如何找出EMP表里面SALARY第N高的employee
2013/12/05 面试题
项目专员岗位职责
2013/12/04 职场文书
会计岗位描述
2014/02/22 职场文书
机关保密承诺书
2014/06/03 职场文书
高一学年自我鉴定范文(3篇)
2014/09/26 职场文书
村当支部个人对照检查材料思想汇报
2014/10/06 职场文书
地震慰问信
2015/02/14 职场文书
复制别人的成功真的会成功吗?
2019/10/17 职场文书
关于k8s环境部署mysql主从的问题
2022/03/13 MySQL