zoukankan      html  css  js  c++  java
  • JavaScript基础知识(一) Prototype Chain

        前些天学习《JavaScript设计模式》(这是一本非常好的书,翻译这本书的作者也很负责,翻译的很好)。其中在介绍JavaScript中如何模拟接口,如何模拟面向对象中的类做了很详尽的解释。但是在学习途中遇到了很多基础知识没有理解,准备用几个章节介绍这些天对这些基础知识学习。最难懂荷花时间最长的就是对JavaScript中Prototype的理解。手头有我从网上搜集的各种资料,在这里贴出百度云的链接,希望想学习的朋友下载学习下。我都整理成PDF格式了。

    1. 链接:http://pan.baidu.com/share/link?shareid=3816985477&uk=2869009987 密码:dwh4

    在介绍Prototype之前先说一个背景知识,ECMA-262-3是javascript的一个规范,各个浏览器厂商都是根据这个ECMA规范定制的javascript功能。ECMAScript就是实现了ECMA-262-3协议的javascript。也就是我们通常所说的javascript。

    在这一个章节中,我将总结有关Prototype Chain,对象是如何创建出来的以及Function于Object的关系等基础知识。

    文中使用的是V8引擎的Nodejs调试的,如果没有学习过node的同学,可以直接嵌套在HTML中,使用aler()方法查看输出,需要指出的是,__proto__在火狐浏览器种才能调用,其他的调用会出错的。

    在讲Prototype之前得先说一下背景知识:

    Object

    Object.prototype是所有对象的祖先(规则一),Object是Javascript的内置函数。在Javascript中,所有的对象都是字典型结构,也就是说,不管对象多么复杂,都可以用JSON来创建并复制。

    1. //创建一个没有属性的对象
    2. var obj = {};
    3. //创建一个有属性的对象
    4. var obj_1 = {name:"angle",age:18,married:false};
    5. //创建有属性,有方法的对象
    6. var obj_2 = {text:"Hello World",say:function(){console.log(this.text)}}

    Function

    Function.prototype是所有函数的原型(规则二),包括构造函数。同Object一样,都是javascript的内置函数。在Javascript中的代码只有function一种形式,我们在写一个function test(){}的时候,只不过是建立了一个function类型的实体。

    1. function Abd(){
    2.   this.a = 1;
    3. }
    4. console.log(typeof Abd);

    输出结果 function。

    所有的function都有显示的原型和隐性的原型,即__proto__和prototype

    Prototype

    在Javascript中有两种形式的原型,一种是隐性的原型 __proto__,另一种是显性的原型 Prototype。我们自定义的方法,

    但是对象只存在隐性原型

    1. function Abd(){
    2.   this.a = 1;
    3. }
    4. var a1 = new Abd();
    5. console.log(a1.prototype);

    输出结果是:undefined

    在javascript中,new关键字创建对象的过程

        1à建立一个新的对象。

        2à将对象内置的原型对象(__proto__)指向其构造函数的Prototype

        3à将该对象作为this参数调用构造函数,完成成员变量等的初始化工作

    在第二步中表明了,所有对象的__proto__都指向了其构造函数的Prototype(规则三),即ABd.prototype

    其实在第三部中隐含了一个过程。即所有对象的constructor都指向当前对象的构造函数

    1. console.log(a1.constructor === Abd);//输出结果为true

    然而每一个函数(function类型)都有一个默认属性,即prototype,这个prototype.constructor指向这个函数(规则四)。看似绕了一个圈圈。

    基本的知识已经介绍完了,我们使用《nodejs开发指南中》讲原型链中的例子,结合图片理解:

    1. function Foo(){
    2. }
    3. var obj = new Object();
    4. var foo = new Foo();

    途中虽然交替穿插着很多箭头,看起来很杂乱,其实只不过是根据上面所说的四条规则索引而已

        à上图中1处为构造出来的对象。他只有隐性的原型,并且原型指向其构造函数的Prototype

        à图中2出可以这么理解,因为function的原型指向的是一个对象,所以这里2处其实就是Foo.prototype。并且Foo.prototype的构造函数constructor指向Foo。同理Foo的__proto__指向其构造函数的原型Function.prototype。因为所有的函数都是Function类型的,Function.prototype的构造函数指向Function(规则三于规则四

        àObject也是一函数。这里就要注意一下了。Object.prototype是没有原型的,所以也是上面的规则一

        à从图中4出可以看出,所有的函数的原型的根都是Function.prototype。这一点符合规则二

    Prototype Chain

    所谓prototype chain(原型链),从上图中可以看出各种杂乱的箭头指向。原型链就是根据Prototype指向的连接。Javascript中对象的继承使用的就是prototype。当然想要使用javascript实现继承还需要做很多包装。这里只是简单的说明原型链的工作原理:

    1. function Sub(){
    2.   this.a = "haha";
    3.   this.b = 5;
    4. }
    5. Sub.prototype.c = function(){//往Sub的原型中添加方法c
    6.   console.log("prototype method");
    7. };
    8. Sub.prototype.d = 6;//往Sub的原型中添加属性d
    9. var testSub = new Sub();
    10. console.log(testSub.a);
    11. console.log(testSub.b);
    12. testSub.c();
    13. console.log(testSub.d);

    输出结果:

    从结果中可以看出,Sub中并没有定义属性c于d,而是在Sub的原型中定义。从这里可以知道,当function中没有定义先关属性的时候,会从其prototype中寻找,直到找到object.prototype为止。从而形成了一条链条。即为prototype chain。

    下面对属性修改的时候原型链是怎么工作的。

    1. function Sub(){
    2.   this.a = "haha";
    3.   this.b = 5;
    4. }
    5. Sub.prototype.a = function(){
    6.   console.log("prototype method");
    7. };
    8. Sub.prototype.b = 6;
    9. Sub.prototype.c = 6;
    10. var testSub = new Sub();
    11. testSub.a = "hello";
    12. testSub.b = 100;
    13. testSub.c = 100;
    14. console.log(testSub.a);
    15. console.log(testSub.b);
    16. console.log(testSub.c);
    17. console.log(Sub.prototype.c);

    结果输出:    

    在代码的第13行中,设置属性c,从结果来看,并没有把Sub中prototype的属性c设置成100.而是在Sub中添加了一个属性c。这是javascript的特性,可以动态的给对象添加属性。在设置属性的值时,如果没有这个属性,不会从原型链中向上追溯,而是直接在对象中添加相应的属性。有点多态的意思。

    当然我所写的这些笔记只是比较浅显的知识,方便回忆。更细致的东西在我分享的那几篇文档中,有兴趣的同学可以下载下来学习交流!

  • 相关阅读:
    Windows常用快捷键
    ArrayList和LinkedList的区别
    ICMP TYPE-CODE查阅表
    dedecmsV5.7 百度编辑器ueditor 多图上传 在线管理 排序问题
    dedecmsV5.7 后台上传m4a的音频之后不展示
    php5.6 上传图片error代码为6 或者 报错“PHP Warning: File upload error
    deducmsV5.7 在{dede:datalist}标签中runphp无效的解决办法
    dedecmsV5.7 插入记录并返回刚插入数据的自增ID
    dedecmsV5.7 调用其他站点的数据库的数据的方法
    dedecmsV5.7 arclist 如何调用副栏目的文章
  • 原文地址:https://www.cnblogs.com/wenlonghor/p/3330870.html
Copyright © 2011-2022 走看看