prototype与[[prototype]]

在有面象对象基础的前提下,来看一段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//Animal构造函数
function  Animal(name){
     this .name = name;
}
//Animal原型对象
Animal.prototype = {
     id: "Animal" ,
     sleep: function (){
         alert( "sleep" );
     }
}
var  dog = new  Animal( "旺才" );
alert(dog.name); //旺才
alert(dog.id); //Animal
dog.sleep() //sleep

其对应的简易内存分配结构图:

现在让我们来解释一下这张内存图的来龙去脉:

首先明确一点[[prototype]]与prototype并不是同一个东西。

  那先来看prototype,每一个函数对象都有一个显示的prototype属性,它代表了对象的原型,更明确的说是代表了由函数对象(构造函数)所创建出来的对象的原型。结合本例,Animal.prototype就是dog的原型,dog所引用的那个对象将从Animal.prototype所引用的对象那继承属性与方法。

  每个对象都有一个名为[[Prototype]]的内部属性,指向于它所对应的原型对象。在本例中dog的[[prototype]]指向Animal.prototype,大家都知道,Animal.prototype也是一个对象,即然是一个对象,那它必然也有[[prototype]]属性指向于它所对应的原型对象,由此便构成了一种链表的结构,这就是原型链的概念。额外要说的是:不同的JS引擎实现者可以将内部[[Prototype]]属性命名为任何名字,并且设置它的可见性,前且只在JS引擎内部使用。虽然无法在JS代码中访问到内部[[Prototype]](FireFox中可以,名字为__proto__因为Mozilla将它公开了),但可以使用对象的 isPrototypeOf()方法进行测试,注意这个方法会在整个Prototype链上进行判断。

注:关于函数对象的具体内容,将在后继的博文中讲解。

属性访问原则

使用obj.propName访问一个对象的属性时,按照下面的步骤进行处理(假设obj的内部[[Prototype]]属性名为__proto__):
1. 如果obj存在propName属性,返回属性的值,否则
2. 如果obj.__proto__为null,返回undefined,否则
3. 返回obj.__proto__.propName
调用对象的方法跟访问属性搜索过程一样,因为方法的函数对象就是对象的一个属性值。
提示: 上面步骤中隐含了一个递归过程,步骤3中obj.__proto__是另外一个对象,同样将采用1, 2, 3这样的步骤来搜索propName属性。

这就是基于Prototype的继承和共享。其中object1的方法fn2来自object2,概念上即object2重写了object3的方法fn2。
JavaScript对象应当都通过prototype链关联起来,最顶层是Object,即对象都派生自Object类型。

结合是上面的理论,让我们再来看一个更加复杂的示例,他明确的解释了prototype、[[prototype]]、原型链以及属性访问的相关要点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//Animal构造函数
function  Animal(name){
     this .name = name;
}
//Animal原型对象
Animal.prototype = {
     id: "Animal" ,
     sleep: function (){
         alert( "sleep" );
     }
}
function  Human(name,age){
     Animal.call( this ,name);
     this .age = age;
}
Human.prototype = new  Animal();
Human.prototype.id = "Human" ;
Human.prototype.say = function (){
     alert( "hello everyone,My name is " + this .name + ",I'm " + this .age+ " and I'm a " + this .id);
}
//Human相关调用
var  jxl = new  Human( '笨蛋' ,25);
alert(jxl.name); //笨蛋
alert(jxl.id); //Human
jxl.say(); //hello everyone,My name is 笨蛋,I'm 25 and I'm a Human
alert(Animal.prototype.isPrototypeOf(jxl)); //true
alert(Object.prototype.isPrototypeOf(jxl)); //true

根据上面的代码,你能画出相应的内存图吗?好,让我们来看一下:

注:prototype的根为Object.prototype,对象Object.prototype的内部[[prototype]]属性为null.

其实,这里还有很多东西可以讲,但在其原理都在这张图上了,可试着调整一下代码的次序,如将Human.prototype.id = "Human";放在Human.prototype = new Animal();的前面,看一下运行结果,解释一下为什么之类的,你可以学到很多。

解释下原型继承的原理。相关推荐

  1. 白话解释 Javascript 原型继承(prototype inheritance)

    来源: 个人博客 白话解释 Javascript 原型继承(prototype inheritance) 什么是继承? 学过"面向对象"的同学们是否还记得,老师整天挂在嘴边的面向对 ...

  2. [css] 解释下 CSS sprites的原理和优缺点分别是什么

    [css] 解释下 CSS sprites的原理和优缺点分别是什么 我来说下我的观点 原理: 多张图合并成一张图优点&解决的问题hover效果,如果是多个图片,网络正常的情况下首次会闪烁一下. ...

  3. JS原型继承工作原理

    为什么80%的码农都做不了架构师?>>>    当查找一个对象的属性时,JS会向上遍历原型链,直到找到给定的属性名称为止,如果没找到就是undefined. 大多数的JS的实现用_p ...

  4. css sprites原理,[css] 第17天 解释下 CSS sprites的原理和优缺点分别是什么?

    1.简介 CSS Sprites在国内很多人叫css精灵,是一种网页图片应用处理方式.它允许将一个页面涉及到的所有零星图片都包含到一张大图中, 利用CSS的"background-image ...

  5. python继承方式是基于原型吗_[译] 为什么原型继承很重要

    五天之前我写了一个关于ES6标准中Class的文章.在里面我介绍了如何用现有的Javascript来模拟类并且介绍了ES6中类的用法,其实它只是一个语法糖.感谢Om Shakar以及Javascrip ...

  6. js原型和原型链_初识JS原型/原型链/原型继承

    本文思路: 原型->原型链->原型继承->基于原型的继承/ES6中的继承->__proto__与prototype 首先我们知道JS中有对象,比如: var 但是在我们没有对这 ...

  7. [css] 请你解释下什么是浮动和它的工作原理是什么?同时浮动会引起什么问题?

    [css] 请你解释下什么是浮动和它的工作原理是什么?同时浮动会引起什么问题? 什么是浮动:我们在做布局的时候用到的一种技术,通过浮动可以让元素左右浮动,然后通过margin调整位置工作原理:使元素脱 ...

  8. 为什么用线程池?解释下线程池参数?线程池处理流程?阻塞队列的作用?为什么是先添加列队而不是先创建最大线程?线程池中线程复用原理?

    为什么用线程池?解释下线程池参数? 1.降低资源消耗:提高线程利用率,降低创建和销毁线程的消耗. 2.提高响应速度:任务来了,直接有线程可用可执行,而不是先创建线程,再执行. 3.提高线程的可管理性: ...

  9. java f else_java else if 为什么比 switch 效率低?最好可以解释下原理

    java else if 为什么比 switch 效率低?最好可以解释下原理 关注:116  答案:2  mip版 解决时间 2021-02-02 06:21 提问者安分守己的小青春 2021-02- ...

最新文章

  1. Mat,Iplimage,vector,vector_vector_Point2f等类型之间的相互转换
  2. 模拟实现常用字符串函数
  3. android动态jar,Android动态加载Jar(包含第三方依赖Jar)
  4. 命名实体识别——日期识别
  5. 记账本开发进程第四天
  6. java .listfiles_Java File.listFiles()
  7. [Oracle]UNIX与Windows 2000上Oracle的差异(I)
  8. 刚刚,Facebook开源了星际争霸AI代码
  9. win10一直正在检查更新_win10一直存在的烦人问题,终于被彻底解决!你会选择更新么?...
  10. linux和windows的ip区别吗,windows与linux ping 显示的ip不一样
  11. “导航技术”学习笔记
  12. 跃迁 成为高手的技术
  13. STM32F072C8T6调试IAP(CAN)记录
  14. 车型数据库设计 mongodb
  15. 计算机占cpu程序,电脑cpu占用过高怎么办 电脑进程CPU占用100%解决办法
  16. 豆瓣读书数据分析实战
  17. 做开发3年,字节跳动二面JVM底层被问得哑口无言
  18. 【乱七八糟的笔记】——前缀树
  19. android insert方法,史上最精炼android四大组件基础总结(忘记了的可以过一遍)
  20. 台式计算机电功率一般多大,笔记本电脑耗电吗?功率一般多大

热门文章

  1. iOS weak的使用
  2. solidworks两条线重合了如何选其中一条
  3. JAVA关于基本数据类型之间进行强制转换底层剖析
  4. tomcat 部署项目设置访问前缀
  5. 数组排序(python)
  6. matlab rbe神经网络代码,径向基神经网络知识介绍
  7. [Java] 初识Java Hello World 我的第一个Java程序
  8. Vue中事件修饰符与键盘事件
  9. 水平凡、lvyecms转齐博X1
  10. 万彩动画大师的JAVA安装不了_[万彩动画大师教程]—安装万彩动画大师出错了重新编辑...