• 原型与原型链


    今天看了github上面的某位大佬对原型与原型链的文章 讲解很透彻 文章下面贴地址

    prototype

    每个函数都有prototype属性,如下

    这个函数的prototype到底是什么呢,是函数的原型吗?

    其实,函数的prototype都会指向一个对象,这个对象 就是调用改构造函数而创建的实例的原型,也就是上图的a b的原型

    什么是原型呢?

    每一个JavaScript对象(null除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型"继承"属性。

    用过一张图来表示构造函数与实例之间的关系

    那么上面的变量 ab是怎么访问到score的prototype.name的呢?

    这里就要提出第二个属性

    ___ proto ___

    这是每个JavaScript对象都会有的属性 叫做_ proto _ 这和属性 指向该对象的原型 即是

    function score () {}
    score.prototype.name = "张三"
    var b= new score()
    b.__proto__.name   //"张三"
    

    这里可以看到 b._ proto_ 是指向score.prototype的 或者我们可以证明

    score.prototype == b.__proto__  //true
    

    现在我们知道

    构造函数 prototype 指向原型 构造函数可以生成实例 实例的 _ proto _ 指向原型

    于是关系图可以这么理解

    这里构造函数 和 实例都指向 原型 那么会不会有 原型指向构造函数与实例呢?

    constructor

    没有指向实例的方法 因为 会有多个实例 但是有指向构造函数的方法 就是constructor 每个原型都有一个constructor属性指向关联的构造函数

    可以看出来constructor指向构造函数本身

    总结一下 现在得出结论

    3

    console.log(score.prototype.constructor == score)
    console.log(score.prototype == a.__proto__)
    

    再更新一下图

    实例与原型

    当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层为止。

    function score () {}
    score.prototype.age="20"    //在原型链上面赋值 age = 20
    var a = new score()
    a.age
    "20"      //age指向原型链上面
    a.age= "10" 
    "10"      //这时候指向a实例上面
    delete a.age;
    a.age
    "20"     //age指向原型链
    

    当实例没有age这个属性 他会在原型链上面找

    当给实例赋值的时候 就会覆盖prototype上面的属性 但是 prototype上面的属性依旧存在

    当将实例上面的age删除的时候 就会依旧打印出原型链上面的属性

    这里思考一个问题 JavaScript万物皆对象 name prototype的对象是什么呢?

    原型的原型

    我们已经讲了原型也是一个对象,既然是对象,我们就可以用最原始的方式创建它

    Object.prototype.name = "张三"
    var obj = new Object();
    console.log(obj.name) // 张三   //和上面同理 来自原型链上面的name
    Object.prototype.constructor == Object
    

    现在关系图再次更新

    原型链

    那 Object.prototype 的原型呢?

    console.log(Object.prototype.__proto__)
    null
    

    null 表示“没有对象”,即该处不应该有值

    所以 Object.prototype.proto 的值为 null 跟 Object.prototype 没有原型,其实表达了一个意思。

    最后整理关系图

    图中由相互关联的原型组成的链状结构就是原型链,也就是蓝色的这条线。

    最让人不注意的就是日常引用要注意的问题

    首先 看下面代码

    function score () {}
    var a = new score()
    console.log(a.constructor == score)
    

    答案是 true

    当获取 a.constructor 时,其实 a中并没有 constructor 属性,当不能读取到constructor 属性时,会从 a的原型也就是 score.prototype 中读取,正好原型中有该属性,所以相当于:

    person.constructor === Person.prototype.constructor
    

    学过java的人可能会将JavaScript的原型链理解为继承 但是 JavaScript里面一直以来都没有这个说法

    你不知道的JavaScript 里面有一句话

    继承意味着复制操作,然而 JavaScript 默认并不会复制对象的属性,相反,JavaScript 只是在两个对象之间创建一个关联,这样,一个对象就可以通过委托访问另一个对象的属性和函数,所以与其叫继承,委托的说法反而更准确些。

    原型与原型链

  • 相关阅读:
    20172302 201720182 《程序设计与数据结构》实验二报告
    20172302 201720182 《程序设计与数据结构》实验一报告
    20172302 《程序设计与数据结构》第五周学习总结
    POJ 1061 青蛙的约会
    hdu 2485 Highways
    UVA 10608
    hdu 1213 how many tables
    java类static成员加载顺寻
    C# virtual,override或者new
    vs无法在WEB服务器上启动调试
  • 原文地址:https://www.cnblogs.com/wuvkcyan/p/8955353.html
Copyright © 2020-2023  润新知