学过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对象中的成员属性和方法。

其中要点有:

  1. prototype是函数(function)的一个必备属性(书面一点的说法是"保留属性")(只要是function,就一定有一个prototype属性)
  2. prototype的值是一个对象
  3. 可以任意修改函数的prototype属性的值。
  4. 一个对象会自动拥有这个对象的构造函数的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 剖析的更多相关文章

  1. [原创]javascript prototype 对象 函数 <精简的美丽......>

    精简的美丽...... javascript prototype 对象 函数 在javascript中我们都知道创建一个对象使用如下代码var x = {}对象可以拥有属性和方法var x = {   ...

  2. javascript prototype原型链的原理

    javascript prototype原型链的原理 说到prototype,就不得不先说下new的过程. 我们先看看这样一段代码: <script type="text/javasc ...

  3. JavaScript Prototype in Plain Language

    非常好的文章: http://javascriptissexy.com/javascript-prototype-in-plain-detailed-language/ jan. 25 2013 14 ...

  4. JavaScript prototype原型用法

    JavaScript对象原型 所有JavaScript对象都从原型继承属性和方法. <!DOCTYPE html> <html> <meta charset=" ...

  5. illustrating javascript prototype & prototype chain

    illustrating javascript prototype & prototype chain 图解 js 原型和原型链 proto & prototype func; // ...

  6. HTML 学习笔记 JavaScript (prototype)

    原博地址:http://www.cnblogs.com/dolphinX/p/3286177.html 原博客的作者是一个非常牛逼的前端大神,我作为一个初学者,在此借助大神的博客进行自己的学习.在这里 ...

  7. 关于 JavaScript prototype __proto__ 一点总结

    http://www.cnblogs.com/wbin91/p/5265163.html 先上代码 function(y) Foo{ this.y = y;} Foo.prototype.x = 10 ...

  8. JavaScript prototype 使用介绍

    用过JavaScript的同学们肯定都对prototype如雷贯耳,但是这究竟是个什么东西却让初学者莫衷一是,只知道函数都会有一个prototype属性,可以为其添加函数供实例访问,其它的就不清楚了, ...

  9. JavaScript——Prototype详探

    用过JavaScript的同学们肯定都对prototype如雷贯耳,但是这究竟是个什么东西却让初学者莫衷一是,只知道函数都会有一个prototype属性,可以为其添加函数供实例访问,其它的就不清楚了, ...

随机推荐

  1. 按钮靠右css小结

    按钮靠右 style="float:right"  ,多按钮排版会相反 按钮内的字体靠右 style="text-align:right" 按钮离右边框距离 s ...

  2. XP系统电脑带安卓手机上网教程(无需adhoc补丁)

    XP系统电脑带安卓手机上网教程(无需adhoc补丁) WIN7系统可以虚拟wifi热点,安卓手机连上这个热点就能上网.XP系统虚拟出来的wifi热点是adhoc形式的,原生的安卓系统并不支持adhoc ...

  3. 如何在腾讯云上搭建一个人力资源Saas

    版权声明:本文由ihr原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/180 来源:腾云阁 https://www.qclo ...

  4. MySQL 函数积累

    IFNULL(expr1,expr2) // 如果expr1不是NULL,IFNULL()返回expr1,否则它返回expr2.IFNULL()返回一个数字或字符串值 IF(expr1,expr2,e ...

  5. python 练习 26

    Python break语句,就像在C语言中,打破了最小封闭for或while循环. break语句用来终止循环语句,即循环条件没有False条件或者序列还没被完全递归完,也会停止执行循环语句. br ...

  6. 各种浏览器css hack

    转载 http://www.cnblogs.com/jikey/archive/2010/06/21/1761924.html IE都能识别*,标准浏览器(如FF)不能识别*:IE6能识别*,但不能识 ...

  7. poj1122 FDNY to the Rescue!(dij+反向建图+输出路径)

    题目链接:poj1122 FDNY to the Rescue! 题意:给出矩阵,矩阵中每个元素tij表示从第i个交叉路口到第j个交叉路口所需时间,若tij为-1则表示两交叉路口之间没有直接路径,再给 ...

  8. Css3动画缩放

    Css3缩放动画 transform-scale() scale();值 0~1   0-隐藏  1-默认 小于0缩放 大于1放大 例:transform:scale(0.98);

  9. 分支语句switch case

    Switch case必须与break一起使用 Break 是跳转语句.与switch case连用的时候是跳出最近的{}. static void Main(string[]args ) { //s ...

  10. PHP 命名空间加载的理解

    关于spl_autoload_register()和__autoload(),相信大多数都会选择前者了? 看两者的用法: //__autoload用法function __autoload($clas ...