function foo(a, b, c)
{
  return a*b*c;
}
alert(foo.length);
alert(typeof foo.constructor);
alert(typeof foo.call);
alert(typeof foo.apply);
alert(typeof foo.prototype);

对于上面的代码,用浏览器运行后你会发现:

  1. length: 提供的是函数的参数个数
  2. prototype: 是一个object
  3. 其它三个都是function

而对于任何一个函数的声明,它都将会具有上面所述的5个property(方法或者属性).

用过JavaScript的同学们肯定都对prototype如雷贯耳,但是这究竟是个什么东西却让初学者莫衷一是,只知道函数都会有一个prototype属性,可以为其添加函数供实例访问,其它的就不清楚了,最近看了一些 JavaScript高级程序设计,终于揭开了其神秘面纱。

每个函数都有一个prototype属性,这个属性是指向一个对象的引用,这个对象称为原型对象,原型对象包含函数实例共享的方法和属性,也就是说将函数用作构造函数调用(使用new操作符调用)的时候,新创建的对象会从原型对象上继承属性和方法。

私有变量、函数

在具体说prototype前说几个相关的东东,可以更好的理解prototype的设计意图。之前写的一篇JavaScript 命名空间博客提到过JavaScript的函数作用域,在函数内定义的变量和函数如果不对外提供接口,那么外部将无法访问到,也就是变为私有变量和私有函数。

function Obj(){
var a=0; //私有变量
var fn=function(){ //私有函数 }
}

这样在函数对象Obj外部无法访问变量a和函数fn,它们就变成私有的,只能在Obj内部使用,即使是函数Obj的实例仍然无法访问这些变量和函数

var o=new Obj();
console.log(o.a); //undefined
console.log(o.fn); //undefined

静态变量、函数

当定义一个函数后通过 “.”为其添加的属性和函数,通过对象本身仍然可以访问得到,但是其实例却访问不到,这样的变量和函数分别被称为静态变量和静态函数,用过Java、C#的同学很好理解静态的含义。

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

实例变量、函数

在面向对象编程中除了一些库函数我们还是希望在对象定义的时候同时定义一些属性和方法,实例化后可以访问,JavaScript也能做到这样

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属性,默认情况下prototype属性会默认获得一个constructor(构造函数)属性,这个属性是一个指向prototype属性所在函数的指针,有些绕了啊,写代码、上图!

function Person(){

            }

根据上图可以看出Person对象会自动获得prototyp属性,而prototype也是一个对象,会自动获得一个constructor属性,该属性正是指向Person对象。

当调用构造函数创建一个实例的时候,实例内部将包含一个内部指针(很多浏览器这个指针名字为__proto__)指向构造函数的prototype,这个连接存在于实例和构造函数的prototype之间,而不是实例与构造函数之间。

function Person(name){
this.name=name;
} Person.prototype.printName=function(){
alert(this.name);
} var person1=new Person('Byron');
var person2=new Person('Frank');

Person的实例person1中包含了name属性,同时自动生成一个__proto__属性,该属性指向Person的prototype,可以访问到prototype内定义的printName方法,大概就是这个样子的

写段程序测试一下看看prototype内属性、方法是能够共享

function Person(name){
this.name=name;
} Person.prototype.share=[]; Person.prototype.printName=function(){
alert(this.name);
} var person1=new Person('Byron');
var person2=new Person('Frank'); person1.share.push(1);
person2.share.push(2);
console.log(person2.share); //[1,2]

果不其然!实际上当代码读取某个对象的某个属性的时候,都会执行一遍搜索,目标是具有给定名字的属性,搜索首先从对象实例开始,如果在实例中找到该属性则返回,如果没有则查找prototype,如果还是没有找到则继续递归prototype的prototype对象,直到找到为止,如果递归到object仍然没有则返回错误。同样道理如果在实例中定义如prototype同名的属性或函数,则会覆盖prototype的属性或函数。

function Person(name){
this.name=name;
} Person.prototype.share=[]; var person=new Person('Byron');
person.share=0; console.log(person.share); //0而不是prototype中的[]

构造简单对象

当然prototype不是专门为解决上面问题而定义的,但是却解决了上面问题。了解了这些知识就可以构建一个科学些的、复用率高的对象,如果希望实例对象的属性或函数则定义到prototype中,如果希望每个实例单独拥有的属性或方法则定义到this中,可以通过构造函数传递实例化参数。

function Person(name){
this.name=name;
} Person.prototype.share=[]; Person.prototype.printName=function(){
alert(this.name);
}
 

javascript prototype学习的更多相关文章

  1. 大量Javascript/JQuery学习教程电子书合集

    [推荐分享]大量Javascript/JQuery学习教程电子书合集,送给有需要的人   不收藏是你的错^_^. 经证实,均可免费下载. 资源名称 资源大小   15天学会jQuery(完整版).pd ...

  2. [推荐分享]大量Javascript/JQuery学习教程电子书合集,送给有需要的人

    不收藏是你的错^_^. 经证实,均可免费下载. 资源名称 资源大小   15天学会jQuery(完整版).pdf 274.79 KB   21天学通JavaScript(第2版)-顾宁燕扫描版.pdf ...

  3. JavaScript 核心学习——继承

    本篇博文讲述如何在 JavaScript 中实现继承,以及原型与原型链的知识,在附录中将会讲述 JavaScript 面向对象的常见错误. ##原型与原型链在 JavaScript 中,使用类将会付出 ...

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

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

  5. 正则表达式(javascript)学习总结

    正则表达式在jquery.linux等随处可见,已经无孔不入.因此有必要对这个工具认真的学习一番.本着认真.严谨的态度,这次总结我花了近一个月的时间.但本文无任何创新之处,属一般性学习总结. 一.思考 ...

  6. JavaScript 基础学习1-day14

    JavaScript 基础学习1 知识预览JavaScript概述二 JavaScript的基础三 JavaScript的对象BOM对象DOM对象实例练习js扩展 JavaScript概述 JavaS ...

  7. JavaScript正则表达式学习笔记(二) - 打怪升级

    本文接上篇,基础部分相对薄弱的同学请移步<JavaScript正则表达式学习笔记(一) - 理论基础>.上文介绍了8种JavaScript正则表达式的属性,本文还会追加介绍几种JavaSc ...

  8. 初步总结javascript中学习DOM之前的知识

    嘿嘿,又到了周末时间,周六其实就是总结这周的学习的,记得周二周三刚开始接触javascript时间,还是不知道怎么学习的,就感觉找不到方向,那时间学习的只是总结了一些简单的定义或者是学习结构,今天就把 ...

  9. JavaScript紧凑学习

    JavaScript紧凑学习 windows本地,调用命令行: win键+R 键入cmd , (cmd是Command 命令行 简称) 目录是C盘下的 C:\Users\Administrator&g ...

随机推荐

  1. 机器学习——大数据与MapReduce

    MapReduce是一个分布式计算框架 优点:可在短时间内完成大量工作 缺点:算法必须经过重写,需要对系统工程有一定的理解 使用数据类型:数值型和标称型数据 MapReduce在大量节点组成的集群上运 ...

  2. Mac 安装HL-340 usb转串口驱动

    下载地址: http://www.wch.cn/download/CH341SER_MAC_ZIP.html 安装,重启. 开机之前按住 command + r 进入recovery模式 终端输入:c ...

  3. Java 从静态代理到动态代理

    先举个静态代理的例子,可能多少有些不恰当,不过本次学习记录,重点不在于通信协议. 比如你在一个机房里,你不能联网,只能连通过一台能连公网的代理机器上网.你发送了一个http请求,将由代理帮你上网. 首 ...

  4. GridView如何将分页数据全部导出为EXCEL?

    GRIDVIEW分页状态下将全部数据导出 protected void Button2_Click(object sender, EventArgs e)//按button2将gridview将数据导 ...

  5. vue给input file绑定函数获取当前上传的对象

    HTML <input type="file" @change="tirggerFile($event)"> JS(vue-methods) tir ...

  6. 7 切片slice

    include 切片 切片的日常用法 切片slice 其本身并不是数组,它指向底层的数组 作为变长数组的替代方案,可以关联底层数组的局部或者 为引用类型. 可以直接创建或从底层数组获取生成. 使用le ...

  7. Android Studio 视图解析

    AS一共同拥有三种视图.我们来分别分析每一种视图的作用. 一.Project视图.(白色字体的文件夹/文件可不关注) 图片中的链接 Gralde介绍:http://stormzhang.com/dev ...

  8. Java实现匿名内部类的简单应用

    在查看数码相片时,通常会使用一款图片查看软件,该软件应该能遍历文件夹下的所有图片并进行显示.编写程序,实现一个图片查看软件,它可以支持6张图片,通过单击不同的按钮就可以查看不同的图片. 思路分析:就是 ...

  9. 九度 1552 座位问题(递推DP)

    题目描述: 计算机学院的男生和女生共n个人要坐成一排玩游戏,因为计算机的女生都非常害羞,男生又很主动,所以活动的组织者要求在任何时候,一个女生的左边或者右边至少有一个女生,即每个女生均不会只与男生相邻 ...

  10. 升级MAC OX上的Python到3.4

    第1步:下载Python3.4 下载地址如下: 下载Mac OS X 64-bit/32-bit installerhttps://www.python.org/downloads/release/p ...