先以一段简单的代码为例:
function Dog(params){
    this.name = param.name;
    this.age = param.age;
    this.bark = function(){
        console.log("汪汪汪!!!");
    };
}
var wc = new Dog({name:"旺财",age:3});
 
 
console.log(Dog.prototype)函数的原型属性
在上面这段代码里,Dog是构造函数(区别普遍函数,构造函数一般大写);wc是构造函数Dog的实例对象。 
那么我们说:当构造函数创建时,会存在一个神秘对象。构造函数的prototype属性(保存着该构造函数的方法和属性)指向该神秘对象,实例化对象的__proto__会指向该神秘对象。
这个神秘对象就是原型。 
wc.__proto__ == Dog.prototype == 原型所在的地址 
下图描述了这种关系: 
构造函数有原型属性,实例对象有原型继承 

原型的两种使用方式

前面说过,我们一旦定义一个函数对象,系统会自动给这个函数对象附上原型属性prototype,这是默认原型链结构

沿用默认原型链结构

Dog.prototype.bark = function(){ console.log("汪汪汪!!!"); }
这样子做,只是给Dog.prototype新添加了一个方法bark,没有破坏默认原型链结构
替换默认原型链结构
Dog.prototype = {
    bark:function(){
    console.log("汪汪汪!!!");
    }
}
这样子做,Dog.prototype指向了新的内存地址,丢失了默认原型链结构的一些默认方法,比如constructor 
下图说明了这两种方式的区别: 

原型的作用

原型的作用是为了实现继承  提高代码的复用
同样的,我们看一段代码:
function Dog(param){
    this.name = param.name;
    this.age = param.age;
    this.bark = function(){
        console.log("汪汪汪!!!");
    };
}
var wc = new Dog({name:"旺财",age:3});
var dh = new Dog({name:"大黄",age:2});
同样的,我们看一下内存分析图: 
console.log(wc.bark == dh.bark);//结果为false
把公有的方法存放在构造函数的原型中,实例对象本身并不存放该方法。这样子做,不论构造函数创建多少个实例,该公有方法始终只存在一个。 
这大大减少了内存的浪费
也许有人会问:在你的图上面wc和dh并没有bark方法,那么它们怎么能调用Dog.prototype里的bark方法?
原因就是js的原型继承特性,在后面谈到原型链的时候会做详细的探讨
 
也许有人会问:既然把公有方法都放在构造函数的原型属性里能节省内存,那么为什么不把name,age等属性也都放在里面呢?
这样做是不对的,对象有共性和特性。比如人都会吃饭睡觉,这是共性。但不同的人姓名年龄不同,这是特性。我们把共性放在原型里,只维护一个。但是特性要放在构造函数里

原型链结构

前面已经说了原型的作用是为了实现继承,提高代码的复用。那么原型实现继承的方法是什么呢?使用原型链! 
何为继承?子类把父类的方法拿来自己用。 
举个栗子:动物会吃饭睡觉,狗继承自动物,于是狗也会了吃饭睡觉;狗会吠叫,旺财和大黄继承自狗,于是旺财也会吠叫 
于是旺财—->狗—->动物就形成了一条链,js原型也有一条类似的链叫做原型链
这条链的原则是:A是B的构造函数 那么(实例化对象__proto__)B.__proto__ == A.prototype;prototype保存着该函数的属性和方法
如上诉的代码:Dog是wc的构造函数 那么wc.__proto__ == Dog.prototype,wc可以使用Dog.prototype里的属性和方法
我们再往上找找原型链吧!
Dog.prototype.__proto__ 是什么? 因为Dog.prototype是Obejct对象,所以Dog.prototype.__proto__ == Object.prototype
Dog.__proto__ 是什么?因为Dog是构造函数,是Function对象,所以Dog.__proto__ == Function.prototype
我们不妨画一下上面的原型链示意图:
Function和Object
这两位都是大佬级的角色了:Function是一切函数的起始,Object是一切对象的起始,他们怎么干一架呢?
    
1.Object也是一个构造函数,只要是函数都是Function的实例,所以:Object.__proto__ == Function.prototype
2.Function也是一个构造函数,所以: Function.__proto__ == Function.prototype
3.Function.prototype是一个”对象?”,所以:Function.prototype.__proto__ == Object.prototype
4.Object.prototype.__proto__ == null
这里有一个巨坑:typeof Function.prototype 结果是function 我也不知道为什么,知道原因的大神请不吝赐教^-^

详聊js中的原型/原型链的更多相关文章

  1. 面试题常考&必考之--js中的难点!!!原型链,原型(__proto__),原型对象(prototype)结合例子更易懂

    1>首先,我们先将函数对象认识清楚: 补充snow的另一种写法: var snow =function(){}; 2>其次:就是原型对象 每当我们定义一个函数对象的时候,这个对象中就会包含 ...

  2. js中的prototype原型解析

    在典型的面向对象的语言中,如java,都存在类(class)的概念,类就是对象的模板,对象就是类的实例.但是在Javascript语言体系中,是不存在类(Class)的概念的,javascript中不 ...

  3. js中函数的原型

    js中每一个构造函数都有一个prototype的属性,prototype指向一个对象,而这个对象的属性和方法都会被构造函数的实例所继承,因此,需要一些共享的属性和方法可以写在构造函数的原型中 1  用 ...

  4. js中构造函数的原型添加成员的两种方式

    首先,js中给原型对象添加属性和方法. 方式一:对象的动态特效 给原型对象添加成员 语法:构造函数.prototype.方法名=function (){ } 方式二:替换原型对象(不是覆盖,而是替换, ...

  5. 详解js中的闭包

    前言 在js中,闭包是一个很重要又相当不容易完全理解的要点,网上关于讲解闭包的文章非常多,但是并不是非常容易读懂,在这里以<javascript高级程序设计>里面的理论为基础.用拆分的方式 ...

  6. 详解js中的寄生组合式继承

    寄生组合式继承是js中最理想的继承方式, 最大限度的节省了内存空间. js中的寄生组合式继承要求是: 1.子对象有父对象属性的副本, 且这些不应该保存在子对象的prototype上.       2. ...

  7. 详解JS中DOM 元素的 attribute 和 property 属性

    一.'表亲戚':attribute和property 为什么称attribute和property为'表亲戚'呢?因为他们既有共同处,也有不同点. attribute 是 dom 元素在文档中作为 h ...

  8. js中使用使用原型(prototype)定义方法的好处

    经常在前端面试或是和其他同行沟通是,在谈到构造在JS定义构造函数的方法是最好使用原型的方式:将方法定义到构造方法的prototype上,这样的好处是,通过该构造函数生成的实例所拥有的方法都是指向一个函 ...

  9. js中__proto__(内部原型)和prototype(构造器原型)的关系

    一.所有构造器/函数的__proto__都指向Function.prototype,它是一个空函数(Empty function) Number.__proto__ === Function.prot ...

随机推荐

  1. VGA驱动时序说明

    根据不同的显示器分辨率,需要不同的刷新频率. 其中显示模式中@60表示显示器1秒钟刷新60帧. 其中时钟(MHz),表示FPGA输出给显示器的时钟频率.需要我们配置PLL的时钟频率为对应频率. 其中行 ...

  2. ASP.NET上传一个文件夹

    之前仿造uploadify写了一个HTML5版的文件上传插件,没看过的朋友可以点此先看一下~得到了不少朋友的好评,我自己也用在了项目中,不论是用户头像上传,还是各种媒体文件的上传,以及各种个性的业务需 ...

  3. 题解 P2674 【《瞿葩的数字游戏》T2-多边形数】

    题目说了很清楚,此题找规律,那么就找规律. 我们观察数列. 令k表示数列的第k个数. 三角形数:1 3 6 10 15 两项相减:1 2 3 4 5 再次相减:1 1 1 1 1 四边形数:1 4 9 ...

  4. XXX is not a function

    今天,一个以前的小伙伴跟我说他遇到了一个问题,调试了将近两天(这家伙一开始不打算干程序员,跑去干了两个月销售,现在又想回来写代码了,所以就自己折腾一个demo,免得面试的时候被问住) 我把他的代码从头 ...

  5. SpringMVC传参注解@RequestParam,@RequestBody,@ResponseBody,@ModelAttribute

    参考文档:https://blog.csdn.net/walkerjong/article/details/7946109 https://www.cnblogs.com/daimajun/p/715 ...

  6. (转)GitHub中PR(Pull request)操作 - 请求合并代码

    转:https://www.jianshu.com/p/b365c743ec8d 前言 本文尽量使用图形工具介绍如何向开源项目提交 Pull Request,一次亲身经历提交 PR 1.fork 项目 ...

  7. ijkplayer阅读学习笔记之从代码上看播放流程

    http://blog.csdn.net/i_do_can/article/details/51374732

  8. C3P0 详解

    定义: C3P0是一个开源的JDBC连接池,目前使用它的开源项目有Hibernate,Spring等. 数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”.预先在缓冲池中放入一定数量的连接,当需 ...

  9. 【洛谷P1036 选数】

    这个题显然用到了深搜的内容 让我们跟着代码找思路 #include<bits/stdc++.h>//万能头 ],ans; inline bool prime(int n)//最简单的判定素 ...

  10. RFC、EMCA-262、TC-39等名词

    请求意见稿(英语:Request For Comments,缩写:RFC)是一系列备忘录. The RFC series contains technical and organizational d ...