最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 简简单单看懂原型链

    正文概述 掘金(炫酷大表哥)   2021-04-22   560

    引言

    从创建一个函数开始,了解函数与函数的prototype,以及对象实例三者之间形成的原型链关系。

    一、创建函数

    function CreateCar(){}
    console.log(CreateCar);
    //function CreateCar(){}
    

    上面我们创建了一个函数,直接打印函数名,得到的结果是函数本身,好像并没有其他的属性。但实际上,只要函数被创建,函数就会默认的添加一个隐形的prototype属性。

    function CreateCar(){}
    console.log(CreateCar.prototype);
    //{constructor: function CreateCar(){}}
    

    打印CreateCar.prototype,得到的结果是一个对象,这个对象就是函数的原型对象。

    二、原型对象

    原型对象初始只有一个constructor属性,这个属性的值指向的是函数本身。

    function CreateCar(){};
    console.log(CreateCar.prototype.constructor === CreateCar);
    //true
    

    原型对象有什么用呢,现在好像看不出来啥,我们把函数当构造函数用试试:

    function CreateCar(){};
    let car = new CreateCar();
    console.log(car);
    //{}
    console.log(car.varieties)
    //undefined
    

    可以看到,创建出来的是个空对象,并且调用对象没有的属性时返回的是undefined,接着对函数的原型对象prototype一顿操作:

    function CreateCar(){};
    CreateCar.prototype.varieties = '小车';
    
    let car1 = new CreateCar();
    console.log(car1);
    //{}
    console.log(car1.varieties);
    //小车
    
    let car2 = new CreateCar();
    console.log(car2);
    //{}
    console.log(car2.varieties);
    //小车
    

    创建的对象car1和car2都是空对象,但是打印它们的varieties都有值且都为'小车',可以明显发现,函数原型对象prototype上的属性,是函数作为构造函数时创建出的对象所共有的。但为什么car1和car2都是空对象,但是却都可以打印出varieties的值呢?这就和原型链扯上关系了。

    三、原型链

    首先,我们知道一个构造函数创建出来的对象,对象上的属性是由函数体内的语句定义的。这些属性我们可以直接看见并打印,请看如下示例。

    function CreateCar(color){
      this.color = color;
    };
    
    let car1 = new CreateCar('白色');
    console.log(car1);
    //{color: "白色"}
    
    let car2 = new CreateCar('黑色');
    console.log(car2);
    //{color: "黑色"}
    

    然后我们已经知道,函数的原型对象上的属性,虽然在对象上看不到,但是会被所有该函数创建出来的对象公用,看如下示例。

    function CreateCar(color){
      this.color = color;
    };
    CreateCar.prototype.varieties = '小车';
    console.log(CreateCar.prototype);
    //{varieties: "小车", constructor: function CreateCar(color){this.color = color;}}
    
    let car1 = new CreateCar('白色');
    console.log(car1);
    //{color: "白色"}
    console.log(car1.varieties);
    //小车
    
    let car2 = new CreateCar('黑色');
    console.log(car2);
    //{color: "黑色"}
    console.log(car2.varieties);
    //小车
    console.log(car2.numberOfwheels);
    //undefined
    

    varieties属性虽然不在对象内展示,但是car1和car2都可以打印出来,这是因为打印varieties的时候,car1和car2都会先在自己身上找varieties,找不到就会去自己构造函数CreateCar的prototype上找(通过__proto__建立关系),找到了就打印出来。而打印car2.numberOfwheels时候,同样car2首先会在自身找,找不到就去构造函数CreateCar的prototype上找,这时候找不到还会继续向上去原生构造函数Object的prototype上找,此时还找不到,就返回undefined了,下面图示这一系列关系。

    简简单单看懂原型链

    那如果对象自身属性和原型对象中属性重名会怎样

    function CreateCar(){
      this.varieties = '大车'
    };
    CreateCar.prototype.varieties = '小车';
    let car = new CreateCar();
    console.log(car);
    //{varieties: "大车"}
    

    可以看到,会优先打印就近找到的属性值。

    总结

    1. 每个函数都有一个原型对象prototype。
    2. 函数原型对象prototype上的属性会被所有该函数创建出来的对象公用。
    3. 调用对象某个值,寻找顺序为:对象自身 → 对象构造函数的prototype → 原生构造函数的prototype → null,这条链即为原型链。
    4. 当对象自身属性和构造函数原型对象的属性重名时,会优先打印就近找到的属性值。

    下载网 » 简简单单看懂原型链

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元