• 原型原型链学习记录


    这是一篇学习笔记。
    个人心得:
    关于原型和原型链这一块,很难,但是,一旦理解,就通了。
    对于这一块,我之前不懂的时候,非要去弄明白,特别痛苦,之后,看到了王福朋老师的闭包原型系列,真的是茅塞顿开!看完之后,我就拿起JavaScript高程3,高程3第6章节,耐心跟着看也就明白了。之后,再去做一些图解,如果能够根据继承画出所有的关系,没有矛盾的点,那就基本没问题了。再到网上找差不多的文章看,如果没有冲突点,那这一块就没问题了。 
    参考的内容:
    http://www.cnblogs.com/wangfupeng1988/p/4001284.html ---王福朋的闭包原型系列
    你不知道的JavaScript   上
    JavaScript高级程序设计  3 
      内容:
        一些名词的解释 +几个图解(所以图片会比较多) 。
        1:简单的实例
        2:完整的实例
        3:重写原型对象
        4:原型继承
     
    原型/继承
    JavaScript中的对象都有一个内置属性 [[prototype]]属性。在表示的时候可以用__proto__表示。
      __proto__ : 每个对象都有这样一个属性,指向该对象的构造函数的prototype的指向
    所有原型链的最后指向都是null。
    除了Object.create(null),直接创建的对象的原型是null/没有原型,即不继承任何属;其余的对象的原型链上null之前都有一个Object.prototype原型对象。 
    Object的prototype对象的[[prototype]]内部属性的值是null。即:Object.prototype.__proto__  === null //true。
     
      所有通过对象直接量创建的对象都有一个共同的原型对象:Object.prototype
     
      通过关键字new和构造函数调用创建的对象的原型就是构造函数的prototype属性所指向的对象。
    (当通过new和构造函数生成实例,实例的原型对象就会锁定)。
         JavaScript中的内建函数以及用户自定义函数都是通过Function 这个函数创建的
     
    所有的函数默认都会拥有一个名为prototype的不可枚举的属性。这个属性指向一个对象,被称为这个函数的原型对象。
    每个原型有一个不可枚举的属性constructor。这个属性引用的是对象关联的函数,即constructor属性的值是一个函数对象。 
     
         而Function是由它自己创建的,所以:  
      Function.__proto__ === Function.prototype ; // true;
     
    new 调用构造函数的一个重要特征
         构造函数的prototype属性值被用做新对象的原型。即通过同一个构造函数创建的对象都继承自同一个对象。
      
       构造函数,原型对象,实例它们都是对象!
     
    instanceof :左边走__proto__,右边走prototype,如果能重合,返回true,否则,返回false。 
           A instanecof  B,一般,A是一个函数,B是一个对象。
     
    使用new的构造函数调用会生成prototype和constructor引用。 
     
    如何理解函数,对象,实例,原型,构造函数之间的关系,图解是非常好的方式,所谓有图有真相
    可以通过原型链(通过__proto__串在一起的原型形成了一条链)把它们串在一起理解。
    1:
    function Foo(){ /*...*/}
    var a1=new Foo();
    var a2=new Foo();
    

    这是一个非常简单的构造函数和实例对象。 

     这样,它们的关系图就出来了。
      实例a1,a2,函数Fun1,原型Fun1.prototype,都是对象.。
      函数Fun1有一个prototype属性,指向一个对象,名为Fun1.prototype,成为Fun1的原型对象。
      原型对象Fun1.prototype 有一个constructor属性,指向该对象关联的函数。
      实例a1,a2都有一个__proto__,指向该实例的构造函数的prototype的指向,并且它们指向的是同一个原型对象,因为a1,a2都是通过new和Fun1构造函数调用生成的实例。
    这个图是比较基本的,并没有展现所有的关系,下一张图会进一步展现它们的关系。
     
    2:
    对象都有[[prototype]]属性,属性值为该对象构造函数的prototype值。
     
     上面的构造函数,原型对象,实例,都是对象,所以它们都有[[prototype]]属性,即它们都继承自某一原型。
      其中null不是实例,null是空对象,什么都没有。
        因为函数Fun1是用户自定义函数,Object,Function是内置函数,都是函数,所以就是通过Function 函数创建的,所以,它们的原型就是Function.prototype.
      Function.prototype.上有call和apply方法,所有的函数都继承自它,所以,所有的函数都能够拥有这两个方法。
    因为:除了Object.create(),无实参直接创建的对象的原型是null/没有原型,即不继承任何属;其余的对象的原型链上null之前都有一个Object.prototype原型对象。    
    所以,原型对象和实例的原型都指向了Object.prototype。
     
    3重写原型对象 :
     
    function Foo(){/*...*/}
    var a1=new Foo();  //用new调用之后就会锁定原型
    Foo.prototype={/*...*/}; //创建一个新原型对象,重写Foo的prototype
    var a2=new Foo();

     图3:

    注:
    新的Foo.prototype 就是Object的实例。
    旧的Foo.prototype 不会消失,依然会存在。因为实例a1的原型会指向它,实例a1继承它,在通过new调用生成实例的时候,a1就会锁定它的原型。
         Foo.prototype.constructor === Object; //true
         a2.constructor === Object; //true
    但是,实际上Foo.prototype和a2都没有constructor属性,它们都是继承自Object.prototype。原型才有constructor这个属性,其他对象的constructor都是继承自原型。
     
     
     
    4:继承
     
    function SuperType(){
        this.property=true;
    }
    SuperType.prototype.getSuperValue=function(){
        return this.property;
    };
    function SubType(){
        this.subproperty=false;
    }
    SubType.prototype=new SuperType(); //继承自SuperType /重写了原型
    
    SubType.prototype.getSuperValue=function(){
        return this.subproperty;
    };
    var instance=new SubType();

    (这张图片源自高程3)

    这里也可以比较清楚地看到对象的关系和对象所拥有的属性集合。

    这是一个简单的原型继承,通过图解关系就可以看到上面代码,方便理解。

    旧的SubType.prototype 依然存在,不过这里它没有实例去引用它。新的SubType.prototype 是作为SuperType的实例存在,继承自SuperType.prototype 。

    从instance开始,通过__proto__连接,直到null,就形成了一条原型链,上层的属性会被下层继承。

    以上就是我的理解,如果有错误,还请各位前边指正,谢谢。
     
  • 相关阅读:
    监听刷新
    判断当前日期是否在[startDate, endDate]区间
    精确计算工具类,提供加减乘除的计算
    常用正则表达式
    高并发
    递归案例
    序列化和反序列化
    web安全
    复杂跨域之CorsFilter源码分析
    springMVC访问根路径问题
  • 原文地址:https://www.cnblogs.com/senhaishusheng/p/7249514.html
Copyright © 2020-2023  润新知