JavaScript面向对象程序设计三 原型模式(上)


Posted in Javascript onDecember 21, 2011

我们创建的每一个函数都有一个prototype(原型)属性,该属性是一个对象,包含可以有特定类型的所有实例共享的属性和方法。使用它的好处就在于可以让所有对象实例共享它所包含的属性和方法,也就是说,不必在构造函数中定义对象的信息,而是可以将这些信息,直接添加在原型对象中,如下所示,还是接着改写前两篇日志中的例子:

function Employee() { 
}; 
Employee.prototype.Name = "Jim"; 
Employee.prototype.Age = 28; 
Employee.prototype.Job = "SoftWare Engineer"; 
Employee.prototype.SayName = function () { 
alert(this.Name); 
}; 
var employee1 = new Employee(); 
employee1.SayName();//Jim 
var emplayee2 = new Employee(); 
emplayee2.SayName(); //Jim 
alert(employee1.SayName = emplayee2.SayName);//true

与构造函数模式不同的是,新对象的这些属性和方法是由所有实例共享的。
以上即是原型模式的一个引子,要理解原型模式的工作原理,就需要了解ECMASCRIPT中原型的性质。
理解原型
在Javascript中,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性。在默认的情况下,虽有prototype属性都会自动获得一个constructor属性,这个属性包含一个指向prototype属性所在函数的指针,而通过这个构造函数,我们还可以继续为原型添加其他属性和方法。
创建了自定义的构造函数之后,其原型属性默认只会取得constructor属性,而至于其他的方法,则都是从Object继承来的。当调用构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的原型属性。要注意的是这个连接存在于实例和构造函数原型属性之间,而不是存在于实例与构造函数之间。
在某些实现中,无法访问到内部属性(_proto_属性),但是在所有实现中都可以通过isPrototypeOf方法来确定对象之间是否存在这种原型关系。从本质上来看,如果对象的_proto_属性指向isPrototypeOf,这个方法就返回true。如下所示:
alert(Employee.prototype.isPrototypeOf(employee1)); //true 
alert(Employee.prototype.isPrototypeOf(employee2));//true

每当代码读取某个对象的某个属性时,都会执行搜索,目标是具有给定名字的属性。搜索最先从对象实例本身开始。如果在实例中找到具有给定名字的属性,则然后该属性的值,如果没有找到,则继续搜索指针指向的原型对象,在原型对象中查找具有给定名字的属性。如果在原型对象中找到这个属性,则返回该属性的值。这也正是对个对象实例共享原型所保存的属性和方法的基本原理。
前面说过,原型最初只包含constructor属性,而该属性也是共享的,因此可以通过对象实例访问
虽然可以通过对象实例访问保存在原型中的值,但是不能通过对象实例重写原型中的值,如果我们在实例中添加一个属性,而该属性与实例原型中的一个属性名称相同,name在实例中创建的属性会屏蔽(.net成为隐藏)原型中的那个属性,如下所示:
function Employee() { 
}; 
Employee.prototype.Name = "Jim"; 
Employee.prototype.Age = 28; 
Employee.prototype.Job = "SoftWare Engineer"; 
Employee.prototype.SayName = function () { 
alert(this.Name); 
}; 
emplayee2.Name = "Sun"; 
alert(employee1.Name); //Jim 
alert(employee2.Name);//Sun

其中employee1.Name的Jim来自原型,二employee2.Name的sun来自实例。
Javascript 相关文章推荐
权威JavaScript 中的内存泄露模式
Aug 13 Javascript
jquery 全局AJAX事件使用代码
Nov 05 Javascript
jquery图片轮播插件仿支付宝2013版全屏图片幻灯片
Apr 03 Javascript
js中自定义方法实现停留几秒sleep
Jul 11 Javascript
jQuery实现ichat在线客服插件
Dec 29 Javascript
浅谈javascript事件取消和阻止冒泡
May 26 Javascript
JS简单循环遍历json数组的方法
Apr 22 Javascript
Bootstrap基本样式学习笔记之表单(3)
Dec 07 Javascript
利用Node.js对文件进行重命名
Mar 12 Javascript
在React中如何优雅的处理事件响应详解
Jul 24 Javascript
javascript计算渐变颜色的实例
Sep 22 Javascript
解决Vue-cli3没有vue.config.js文件夹及配置vue项目域名的问题
Dec 04 Vue.js
jquery $.getJSON()跨域请求
Dec 21 #Javascript
jquery事件机制扩展插件 jquery鼠标右键事件
Dec 21 #Javascript
DIV外区域Click后关闭DIV的实现代码
Dec 21 #Javascript
用JSON做数据传输格式中的一些问题总结
Dec 21 #Javascript
40款非常有用的 jQuery 插件推荐(系列一)
Dec 21 #Javascript
这段js代码得节约你多少时间
Dec 20 #Javascript
js实现的仿新浪微博完美的时间组件升级版
Dec 20 #Javascript
You might like
MySQL中create table语句的基本语法是
2007/01/15 PHP
Memcache 在PHP中的使用技巧
2010/02/08 PHP
Apache实现Web Server负载均衡详解(不考虑Session版)
2013/07/05 PHP
PHP 极验验证码实例讲解
2016/09/29 PHP
php与python实现的线程池多线程爬虫功能示例
2016/10/12 PHP
获取当前网页document.url location.href区别总结
2008/05/10 Javascript
仅用[]()+!等符号就足以实现几乎任意Javascript代码
2010/03/01 Javascript
select 控制网页内容隐藏于显示的实现代码
2010/05/25 Javascript
javascript 窗口加载蒙板 内嵌网页内容
2010/11/19 Javascript
三级下拉菜单的js实现代码
2011/05/23 Javascript
批量修改标签css样式以input标签为例
2014/07/31 Javascript
jquery datatable后台封装数据示例代码
2014/08/07 Javascript
jquery 中ajax执行的优先级
2015/06/22 Javascript
JQuery导航菜单选择特效
2016/04/11 Javascript
JavaScript编写页面半透明遮罩效果的简单示例
2016/05/09 Javascript
vue-cli+webpack在生成的项目中使用bootstrap实例代码
2017/05/26 Javascript
详解用函数式编程对JavaScript进行断舍离
2017/09/18 Javascript
改进 JavaScript 和 Rust 的互操作性并深入认识 wasm-bindgen 组件
2019/07/13 Javascript
详解vuex的简单todolist例子
2019/07/14 Javascript
将Django使用的数据库从MySQL迁移到PostgreSQL的教程
2015/04/11 Python
使用Python中的tkinter模块作图的方法
2017/02/07 Python
flask框架单元测试原理与用法实例分析
2019/07/23 Python
Python小整数对象池和字符串intern实例解析
2020/03/21 Python
政法大学毕业生自荐信范文
2014/01/01 职场文书
活动总结报告范文
2014/05/04 职场文书
2014国庆节主题活动方案:快乐的国庆节
2014/09/16 职场文书
仲裁协议书
2014/09/26 职场文书
四风对照检查剖析材料
2014/10/07 职场文书
党的群众路线教育实践活动个人批评与自我批评
2014/10/16 职场文书
个人年终总结范文
2015/03/09 职场文书
朋友聚会祝酒词
2015/08/10 职场文书
保险公司2016开门红口号集锦
2015/12/24 职场文书
李白经典诗之一:全文无一“月”字,却句句有月
2019/07/12 职场文书
Python如何使用logging为Flask增加logid
2021/03/30 Python
详解Golang如何优雅的终止一个服务
2022/03/21 Golang
改造DE1103三步曲
2022/04/07 无线电