javascript prototype 剖析
学过javascript的一定对prototype不陌生,但是这个究竟是个什么东西,就不一定很清楚。
我们先对prototype进行一个定义:每个函数都有一个prototype属性,这个属性是指向一个对象的引用(通俗点说就是这个prototype属性的值是这个对象的引用),这个对象称为原型对象,原型对象包含函数实例共享的方法和属性,也就是说将函数用作构造函数调用(使用new操作符调用)的时候,新创建的对象会从原型对象上继承属性和方法。
为了更好的理解prototype的设计意图,我们先来说几个概念。
私有的变量和函数:
在函数内定义的变量和函数,如果不对外提供接口,那么外部将无法访问到,也就是变为私有变量和私有函数。
function Obj() {
var a = 0; //私有变量
var fn =function(){ //私有函数
//code
}
}
这样在函数对象Obj外部无法访问变量a和函数fn,它们就变成私有的,只能在Obj内部使用,即使是函数Obj的实例仍然无法访问到这些变量和函数:
代码如下:
var o = new Obj();
console.log(o.a); //undefined
console.log(o.fn); //undefined
静态变量和函数
当定义一个函数后,通过"."为其添加属性和函数,通过函数对象本身可以访问到,但是其实例却访问不到,这样的变量和函数分别被称为静态变量和静态函数。
代码如下:
function Obj(){ } Obj.a=0; //静态变量 Obj.fn=function(){
//静态函数 } console.log(Obj.a);
//0
console.log(typeof Obj.fn); //function var
o=new Obj();
console.log(o.a); //undefined
console.log(typeof o.fn); //undefined
实例变量和函数
在面向对象编程中,我们希望在构造函数定义的时候,能够定义一些属性和方法,实例化后可以访问。
function Obj(){
this.a=[]; //实例变量
this.fn=function(){ //实例方法 }
} console.log(typeof Obj.a); //undefined
console.log(typeof Obj.fn); //undefined var o=new
Obj();
console.log(typeof o.a); //object
console.log(typeof o.fn); //function
再来看一下代码:
function Obj(){
this.a=[]; //实例变量
this.fn=function(){ //实例方法 }
} var o1=new Obj();
o1.a.push(1);
o1.fn={};
console.log(o1.a);
//[1]
console.log(typeof o1.fn); //object
var
o2=new Obj();
console.log(o2.a); //[]
console.log(typeof o2.fn); //function
上面的代码运行结果完全符合预期,说明一个问题,在o1中修改了a和fn,o2中没有改变,由于数组和函数都是引用类型,这就说明o1中的属性及方法和o2中的属性及方法虽然同名但却不是同一个引用,而是对Obj对象定义的属性和方法的一个复制。
这种机制对属性来说没有什么问题,但是对方法来说问题就很大,因为方法都是在做完全一样的功能,但是却有两份复制,如果一个对象有上千的实例方法,那么每个实例都要保存上千个复制,这显然是不科学的,如何解决?prototype就这样诞生了。
prototype
"prototype"字面翻译是"原型",是JavaScript实现继承的主要手段。prototype是JavaScript中函数(function)的一个保留属性,它的值是一个对象(我们称为"prototype对象或原型对象")。
通过函数作为构造函数构造出来的对象都自动拥有构造函数的prototype对象中的成员属性和方法。
其中要点有:
- prototype是函数(function)的一个必备属性(书面一点的说法是"保留属性")(只要是function,就一定有一个prototype属性)
- prototype的值是一个对象
- 可以任意修改函数的prototype属性的值。
- 一个对象会自动拥有这个对象的构造函数的prototype的成员属性和方法
//定义一个函数(构造函数),并定义一些属性和方法用来给另外一个构造函数构造出来的对象继承
var function1=function(){
this.name="function1";
this.saySomething=function(){alert("This's a method of "+this.name);}//定义一个方法
}
//定义另外一个构造函数
var function2=function(){
}
//将构造函数function2的prototype属性设置为一个由function1构造出来的对象,以便使由function2构造出来的对象(并且原本是没有任何属性和方法的对象)拥有function1的属性和方法
function2.prototype=new function1();
var obj1=new function1();
//obj1本来什么成员也没有,多得prototype机制,是它坐享其成地拥有了function1对象的属性和方法。
obj1.saySomething();
那么prototype背后是怎么工作的呢?这里不得不提一个跟prototype一样是系统保留的属性:__proto__
__proto___是一个对象自动拥有的内置属性,指向这个对象的构造函数的prototype对象,才使这个对象认识了它的构造函数的prototype对象,并且拥有了这个prototype对象的属性和方法,比如Person构造函数:
javascript prototype 剖析的更多相关文章
- [原创]javascript prototype 对象 函数 <精简的美丽......>
精简的美丽...... javascript prototype 对象 函数 在javascript中我们都知道创建一个对象使用如下代码var x = {}对象可以拥有属性和方法var x = { ...
- javascript prototype原型链的原理
javascript prototype原型链的原理 说到prototype,就不得不先说下new的过程. 我们先看看这样一段代码: <script type="text/javasc ...
- JavaScript Prototype in Plain Language
非常好的文章: http://javascriptissexy.com/javascript-prototype-in-plain-detailed-language/ jan. 25 2013 14 ...
- JavaScript prototype原型用法
JavaScript对象原型 所有JavaScript对象都从原型继承属性和方法. <!DOCTYPE html> <html> <meta charset=" ...
- illustrating javascript prototype & prototype chain
illustrating javascript prototype & prototype chain 图解 js 原型和原型链 proto & prototype func; // ...
- HTML 学习笔记 JavaScript (prototype)
原博地址:http://www.cnblogs.com/dolphinX/p/3286177.html 原博客的作者是一个非常牛逼的前端大神,我作为一个初学者,在此借助大神的博客进行自己的学习.在这里 ...
- 关于 JavaScript prototype __proto__ 一点总结
http://www.cnblogs.com/wbin91/p/5265163.html 先上代码 function(y) Foo{ this.y = y;} Foo.prototype.x = 10 ...
- JavaScript prototype 使用介绍
用过JavaScript的同学们肯定都对prototype如雷贯耳,但是这究竟是个什么东西却让初学者莫衷一是,只知道函数都会有一个prototype属性,可以为其添加函数供实例访问,其它的就不清楚了, ...
- JavaScript——Prototype详探
用过JavaScript的同学们肯定都对prototype如雷贯耳,但是这究竟是个什么东西却让初学者莫衷一是,只知道函数都会有一个prototype属性,可以为其添加函数供实例访问,其它的就不清楚了, ...
随机推荐
- Redis常用的基本命令整理
SET key value [EX seconds] [PX milliseconds] [NX|XX] 设置缓存 K-V,如果 key 已经存在,则重写 EX seconds -- 设置过期时间, ...
- VB6 GDI+ 入门教程[5] 基础绘图小结
http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[5] 基础绘图小结 2009 年 6 月 18 日 4条 ...
- css3做的动画
基于放大缩小: http://www.credero.etall.cn/demo/jwtplay/3/content05.html 基于3d: http://www.credero.etall.cn/ ...
- 在唯一密钥属性“name”设置为“ScriptHandlerFactory”时,无法添加类型为“add”的重复集合项
出错原因:同一根目录下有两个相同的WebConfig文件 解决办法:删除子其中一个webConfig文件. 详细:
- 百度地图API:利用瓦片生成工具,自定义背景图片
参考酸奶小妹的博文<[百度地图API]如何制作一张魔兽地图!!——CS地图也可以,哈哈哈> (http://www.cnblogs.com/milkmap/archive/2011/05/ ...
- How to decide on the correct number of clusters?
Determining the number of clusters/segments in hierarchical clustering/segmentation algorithms 由于uni ...
- JVM调优(这里主要是针对优化基于分布式Mahout的推荐引擎)
优化推荐系统的JVM关键参数 -Xmx 设定Java允许使用的最大堆空间.例如-Xmx512m表示堆空间上限为512MB -server 现代JVM有两个重要标志:-client和-server,分别 ...
- ArangoDB介绍——未知架构和底层原理
ArangoDB介绍 ArangoDB是一个开源NoSQL数据库,官网:https://www.ArangoDB.org/ArangoDB支持灵活的数据模型,比如文档Document.图Graph以及 ...
- 转载python2进制打包相关
Python模块——struct(字节流,组包拆包实现) http://www.linuxidc.com/Linux/2014-02/97158.htm [日期:2014-02-24] 来源:Linu ...
- 腾讯大规模Hadoop集群实践 [转程序员杂志]
TDW(Tencent distributed Data Warehouse,腾讯分布式数据仓库)基于开源软件Hadoop和Hive进行构建,打破了传统数据仓库不能线性扩展.可控性差的局限,并且根据腾 ...