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的特性,可以动态的给对象添加属性。在设置属性的值时,如果没有这个属性,不会从原型链中向上追溯,而是直接在对象中添加相应的属性。有点多态的意思。

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

  • 相关阅读:
    ZOJ 1002 Fire Net (火力网)
    UVa OJ 117 The Postal Worker Rings Once (让邮差只走一圈)
    UVa OJ 118 Mutant Flatworld Explorers (变体扁平世界探索器)
    UVa OJ 103 Stacking Boxes (嵌套盒子)
    UVa OJ 110 MetaLoopless Sorts (无循环元排序)
    第一次遇到使用NSNull的场景
    NSURL使用浅析
    从CNTV下载《小小智慧树》
    NSDictionary and NSMutableDictionary
    Category in static library
  • 原文地址:https://www.cnblogs.com/wenlonghor/p/3330870.html
Copyright © 2011-2022 走看看