`
talentluke
  • 浏览: 600819 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

深度理解原型链

 
阅读更多

摘自http://www.cnblogs.com/maorongmaomao/archive/2012/08/29/2662258.html

 

写在开始之前:

  早就想要好好总结下javascript的基础知识了,所以从这篇文章起,我会开始总结各种js的语法知识,作为一名以js开发为生计的前端工 程师,深深的着迷于js的语言魅力,而js最吸引人最强大的地方,便在于他独特的语法,能深刻的理解js的语法,是作为一个前端工程师的基本素质,在这 里,笔者在总结的同时,也希望前端朋友们给予自己的补充和见解。那么就让我们从js最最独特的语法,闭包,原型,词法作用域开始,接下来,笔者也会讨论 this,正则,浏览器的能力检测,事件代理等细节问题,以及html5,css3等前沿领域,今天我先试着总结下原型链相关的知识。笔者的经验和知识也 许会有很多不足之处,欢迎大家的更正与建议。

 

1.首先要知道的:

  什么是原型链呢?

  我们首先来说说继承,继承是面向对象语言的重要机制,通俗地讲就是子类可以拥有父类的方法和属性,js的原型链实际上也是一种继承,在ECMAScript标准中,只支持实现继承,而其实现实现继承就是主要依靠于原型链实现的。

  那么,我们再来说说原型,原型其实就是上述所说的继承中的父类。

  这样,原型链 显而易见的 可以理解为,利用原型串起一个继承链,让一个引用类型继承另一个引用类型的属性和方法,再以此类推下去。

  构造函数,原型,与实例的关系:

  这三者的关系用一句话概括为,每个构造函数都有一个原型,当new 一个构造函数的时候就会生成一个原型链上携带该构造函数的原型的实例。

2.原型链的生成过程:  

  上面基本了解了原型链的相关知识,那么原型链的生成过程是什么呢?

复制代码
1 function parent(){
  this.parent = "world";
2 }
3 parent.prototype = {
4    a : function(){
5    },
6    b : "hello"
7 }
8  var child = new parent()
复制代码

   而child就是parent的一个实例,在执行构造函数的时候,js引擎创建一个空白对象,把__proto__指向parent的 prototype,然后把这个对象作为this调用parent进行初始化,这样一个简单的原型链就形成了 即 child --> parent.prototye -->Object.prototype。

    prototype,constructor,__proto__ : 

  上面多次提到这几个属性,在原型链的概念中,如果能理解这几个属性的关系,那么离胜利就不远了。下面我们逐一的谈谈这几个属性:

  1.prototype

  prototype是构造函数的属性,指的就是构造函数的原型,在生成实例的时候,js会根据构造函数的prototype属性将该属性下的对象生成为父类,

     注意,只有构造函数这个属性才有这种效果哦~如果一个构造函数没有指定该属性,那么该属性下的__proto__会默认的指向原生Object的原型对象,该属性会变成一个对象,其中constructor属性指向本身。

  2.constructor

     constructor,如果通俗的理解,可以理解成原型对象的构造函数,当把一个对象(对象字面量)赋给一个构造函数的原型,constructor 会被复写,如果没有进行prototype的操作的话,constructor是函数声明时指定的,指定为本身:

  例如:

  function A() {}
  则 A.prototype.constructor === A;

但是这个属性往往是不准确的:

1 function A() {}
2 function B() {}
3 B.prototype = new A();
4 var b = new B();
5 b.constructor; // A

  上面的代码,按照constructor的含义,b的constructor应该指向B,但是确指向了A,原因如下

    A没有进行prototype操作,所以其constructor指向本身;
  B.prototype = new A();之后B.prototype被复写为A的实例,
  则B.prototype.constructor === A;
  而b是B的实例则b.constructor === A;
 
  所以constructor这个属性是不准确的,不推荐大家关注与使用。
  

  如果想要实现继承,一般要进行constructor修复,即:
  B.prototype = new A();
  B.prototype.constructor = B;

  3.__proto__
  可以这么说,js的原型链就是通过这个属性串联起来的,__proto__属性指向他的父类,在调用一个对象的属性或者方法的时候就是通过__proto__这一属性指向的对象一层一层的向上查找的。上面的一句:在生成实例的时候,js会根据构造函数的prototype属性将该属性下的对象生成为父类,在这里可以改为,在生成实例的时候,js会根据构造函数的prototype属性将该属性下的对象引用到实例的__proto__属性下。

     

复制代码
 1 function parent(){
 2     this.a = "world";
 3     this.b = "world";
 4 }
 5 parent.prototype = {
 6    a : "aaa",
 7    b : "bbb",
 8    c : "!" 
 9 }
10 function temp(){
11    this.a = "hello";
12 }
13 temp.prototype = new parent();
14 var child = new temp();
15 console.log(child.a +" " + child.b+child.c);//hello world!
复制代码

  上面的代码运行结果就为 : “hello world!”生成的原型链即是

  child(temp的实例) > __proto__ > temp.prototype(parent的实例) > __proto__  >parent.prototype > __proto__ > Object.prototype >__proto__ > null

3.原型链的调用

  如上所示,原型链由__proto__属性串联而成,经过上面的分析,调用的理解就变得很简单了,比如上例的原型链中,当调用child.c属性时,那么程序会按如下方式运行:

  在child本层查找c,查询未果,会通过__proto__属性向上查找temp.prototype,查找未果,继续沿着 __proto__向上查找parent.prototype,oyeah~终于找到了~所以child.c在这里就会是 parent.prototype.c了~

  怎么样,简单吧^ ^

 

最后的最后,呈上一个常用函数给大家:

  

复制代码
 1 function A() {
 2      // do something here
 3 }
 4 A.prototype = {
 5      a : 'aaa',
 6      b : function() {
 7      }
 8 };
 9  function B() {
10 }
11 extend(B, A);
12 function extend(child, parent) {
13      function temp() {
14             this.constructor = child;
15     }
16      temp.prototype = parent.prototype;
17      child.prototype = new temp();
18 }
复制代码

  extend函数 两个参数都为构造函数,目的是让一个构造函数(子类)继承另一个构造函数(父类)的原型,并且不调用父类的构造函数(有时候构造函数会需要一些参数或者做一些事情破坏了原型链),这个方法可以用来生成想要的原型链哦。

分享到:
评论

相关推荐

    深度探讨javascript函数的原型链和闭包

    理解函数的原型链和闭包对于深入掌握JavaScript至关重要。 首先,让我们看看函数的定义方式。在JavaScript中,我们可以使用`function`关键字直接定义函数,如`function fn(a, b) {}`。此外,函数也可以通过赋值语句...

    SCM供应链系统仿真原型

    SCM(供应链管理)供应链系统仿真原型是一种模拟实际供应链流程的工具,用于帮助企业和个人理解、分析和优化供应链运营。...通过运用仿真技术,原型能够提供深度洞察,推动更有效的决策,以提升整体供应链绩效。

    SoftUni-Exercise

    7. 对象操作:深度理解原型链、构造函数、`new`关键字,以及`Object.create`、`Object.keys`等对象相关的方法。 8. 异步编程:学习如何处理非阻塞I/O,如回调函数、Promise、async/await等,这是现代JavaScript开发...

    javascript prototype的深度探索不是原型继承那么简单第1/3页

    在原型链中,每个对象都会在其原型链上有一个位置,原型链的顶端通常是Object构造函数的原型。这个原型对象是所有JavaScript对象共享的,它包含了所有对象可以共享的默认属性和方法。 此外,JavaScript的每一个函数...

    js对象实例详解(JavaScript对象深度剖析,深度理解js对象)

    3、继承与原型链 4、对象的深度克隆 5、一些Object的方法与需要注意的点 6、ES6新增特性 下面反复提到实例对象和原型对象,通过构造函数 new 出来的本文称作 实例对象,构造函数的原型属性本文称作 原型对象。 创建...

    JavaScript深度剖析.zip

    3. **原型与原型链**:JavaScript中的对象继承是通过原型和原型链实现的,理解原型对象、__proto__属性和prototype属性对于理解对象关系至关重要。 4. **异步编程**:JavaScript是单线程的,但通过事件循环和回调...

    x1-文本小节-知识深度很重要.md

    例如,面试官可能会针对JavaScript考察作用域、闭包、原型链、异步编程等概念的深入理解;在Vue和React方面,可能会探讨虚拟DOM的工作原理、组件生命周期、状态管理等核心概念。 面试官之所以重视技术深度,是因为...

    深度克隆的事例代码

    这种方法简单易用,但不适用于包含函数或循环引用的对象,因为它不能处理函数和会丢失原型链信息。 ### Python中的深度克隆 Python的`copy`模块提供了`deepcopy()`函数,可以方便地实现深度克隆: ```python ...

    jQuery_的原型关系图

    当试图访问对象的一个属性时,JavaScript会首先在当前对象中查找,如果找不到,则会沿着原型链向上查找,直到找到该属性或者到达原型链的顶端(即`null`)。 在jQuery中,核心的`$`函数实际上是一个构造函数,用于...

    JavaScript深度剖析课件下载

    3. **原型和继承**:JavaScript中的对象可以通过原型链实现继承,这与传统的类继承有所不同,理解和熟练运用原型链对于开发面向对象的程序至关重要。 4. **异步编程**:JavaScript的非阻塞特性使得异步编程成为可能...

    一个用于对象深度克隆的同构和可配置javascript函数

    3. **保留原型链**:复制的对象应保持与原对象相同的构造函数和原型链。 4. **性能优化**:对于大型或循环引用的对象,深度克隆函数需要有良好的性能表现,避免无限递归和内存消耗过大。 5. **可配置性**:允许设置...

    中职语文“深度学习”探究.pdf

    比如在教授《项链》时,可围绕人物论、主题辨析和原型溯源开展深度探讨,让学生在历史背景和比较分析中理解人物变化和作品主题。 【数据分析】和【数据研究】在现代教育中也扮演着重要角色。教师可以通过收集和分析...

    2.深度学习开发框架.pptx

    例如,TensorFlow适用于需要高度灵活性和大规模并行计算的项目,PyTorch则更适合快速实验和原型设计,而PaddlePaddle以其对中国开发者友好的特性,成为国内许多企业首选的深度学习工具。通过深入学习这些框架,...

    GitHub上最受欢迎的57个深度学习开源项目

    这一技术在数字艺术领域引起了极大的兴趣,同时也促进了人们对深度学习背后机制的理解。 #### 5. Keras **链接**: [https://github.com/fchollet/keras](https://github.com/fchollet/keras) Keras是一个高级神经...

    第5章 前端面试技能拼图3 :知识深度 - 原理和源码

    这包括但不限于变量作用域、闭包、原型链、异步编程(Promise、async/await)、事件循环和回调队列等核心概念。掌握它们的原理,能帮助你在面试中解释复杂的代码行为,展现你的逻辑思维能力。 其次,浏览器工作原理...

    不是原型继承那么简单!!prototype的深度探索

    当一个对象没有定义某个属性或方法时,JavaScript 引擎会沿着原型链向上查找,直到找到相应的属性或方法为止。 在 JavaScript 中,类(Class)和对象实例(Instance)之间的关系是一种“创建”关系。类可以看作是...

    基于深度学习理念的高阶思维发展探索.pdf

    深度学习是一种先进的教育理念,强调对知识的深入理解和综合运用,而非仅仅停留在表面的记忆层面上。在小学数学教育中,发展学生的高阶思维能力是深度学习的重要体现。高阶思维包括分析、综合、评估和创新等能力,...

    精品--深度学习框架配置和实践.zip

    总的来说,这份压缩包提供的资料将引导你深入理解深度学习框架的配置和实践,帮助你建立起从理论到实际操作的桥梁,提升你在深度学习领域的技能。记得动手实践,不断尝试和改进,这是掌握任何技术的关键。

    Python-深度学习资源集锦

    2. 深度学习理论:理解神经网络的工作原理,包括前馈神经网络、卷积神经网络(CNN)、循环神经网络(RNN)及其变种如LSTM和GRU,以及自编码器和生成对抗网络(GAN)。 3. 实践项目:通过实际项目熟悉深度学习框架的...

Global site tag (gtag.js) - Google Analytics