学过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. 队列 - 从零开始实现by C++

    参考链接:数据结构探险-队列篇 数据结构太重要了,不学好是没法进行软件开发的. C++写数据结构基本套路:一个.h文件写该数据结构类的接口:一个.cpp文件写接口的具体实现:一个main.cpp用于测 ...

  2. jquery 全选功能

    1.直接全选(复选框名字要统一) <input type="CHECKBOX" id="cbSelectAll" onclick="$('inp ...

  3. IE6/IE7下:inline-block解决方案

    IE6/IE7下对display:inline-block的支持性不好. 1.inline元素的display属性设置为inline-block时,所有的浏览器都支持: 2.block元素的displ ...

  4. Android系统启动过程-uBoot+Kernel+Android

    摘要:本文是参考大量网上资源在结合自己查看源代码总结出来的,让自己同时也让大家加深对Android系统启动过程有一个更加深入的了解!再次强调,本文的大多数功劳应归功于那些原创者们,同时一些必要的参考链 ...

  5. 《javascript高级程序设计》第八章 The Browser Object Model

    8.1 window 对象 8.1.1 全局作用域 8.1.2 窗口关系及框架 8.1.3 窗口位置 8.1.4 窗口大小 8.1.5 导航和打开窗口 8.1.6 间歇调用和超时调用 8.1.7 系统 ...

  6. (16)odoo8 API 指南

    http://odoo-new-api-guide-line.readthedocs.org/en/latest/index.html

  7. css样式初始化

    不同的浏览器对有些标签的默认显示是不同的,对css样式初始化可以实现样式的统一,消除不同浏览器间页面显示的差异性... 一般初始化方式为:*{margin:0:padding:0:}

  8. 实验一 Java开发环境的熟悉境的熟悉

    - 运行结果: (一)命令行下Java程序开发 (二)Eclipse下Java程序开发.调试 设置断点和单步运行 单步运行:Step Into(快捷捷F5)和Step Over(快捷捷F5) 使程序直 ...

  9. NetworkComms框架介绍 序列化并发送对象

    NetworkComms网络通信框架序言 英文原文:http://www.networkcomms.net/custom-objects/ NetworkComms.Net网络库,支持发送自定义类,并 ...

  10. ant非法字符:\65279 错误

    ant非法字符:\65279 错误前段时间用ant把项目打包,遇到一个问题:编译java文件的时候,有些java文件报非法字符 \65279错误,在网上找和很多方法,也试了很多方法,换JDK,网上说的 ...