• 对js中的原型,原型链的理解


    参考自:https://www.cnblogs.com/ningyn0712/p/6216711.html

    javascript语言是一种面向对象的语言,它没有"子类"和"父类"的概念,里面所有的数据类型都是对象,js通过原型链将这些联系起来。

    构造函数是一种特殊的方法,主要用来在创建对象时初始化对象。每个构造函数都有prototype(原型)(箭头函数以及Function.prototype.bind()没有)属性, 这个prototype(原型)属性是一个指针,指向一个对象,这个对象的用途是包含特定类型的所有实例共享的 属性和方法,即这个原型对象是用来给实例对象共享属性和方法的。每个实例对象的__proto__都指向这个 构造函数/类的prototype属性。

    什么是原型链?当对象查找一个属性的时候,如果没有在自身找到,那么就会查找自身的原型,如果原型还没有找到,那么会继续查找原型的原型,直到找到 Object.prototype 的原型时,此时原型为 null,查找停止。 这种通过 通过原型链接的逐级向上的查找链被称为原型链 
    链接:https://juejin.cn/post/6934500357091360781

    1、首先了解一下构造函数

    构造函数是用来创建特定类型的对象。

    先定义一个People的构造函数

    function People(name){
        this.name = name;
        this.sex = 'male'
    }
    // 通过new命令来生成两个个person实例
    const person1 = new People()
    const person2 = new People()
    person2.sex = 'nv';
    console.log(person1.sex)      // male 
    console.log(person2.sex)      // nv
    // 此时,People就是实例对象person1和person2的原型。

    new出来的person1对象此时已经和Female再无联系了!也就是说每一个new出来的实例都有自己的属性和方法的副本,是独立的的!修改其中一个不会影响另一个!

    此时,People就是实例对象person1和person2的原型, 理解为person1和person2是被People创建出来的。

    说A是B的原型,必有B.__proto__ === A.prototype;

    若我们希望给每个实例对象增加一个eyesColor属性,且通过People生成的实例中

    eyesColor = 'red';

    那么原型对象就即将登场了!给每一个构造函数都设置一个prototype属性,这个属性就指向原型对象。其实原型对象就只是个普通对象,里面存放着所有实例对象需要共享的属性和方法!所以,我们把需要共享的放到原型对象里,把那些不需要共享的属性和方法存在在构造函数里!

    People.prototype.eyesColor = 'red';
    console.log(person1.eyesColor)      // red 
    console.log(person2.eyesColor)      // red
     // 实例一旦创建出来就会自动引用prototype对象的属性和方法!所以实例对象的属性和方法一般分为两种:一种是自身的,一种是引用自prototype的。
    2、原型链的理解

    当找某个对象的某个属性的时候,首先从对象实例本身开始,如果在实例中找到了该属性,则返回该属性的值,如果没有找到,则顺着原型链指针向上,到原型对象中去找。

    这里要提一点,如果为对象实例添加了一个属性与原型中同名,则该属性会屏蔽掉原型中的同名属性,不会去修改它!使用delete可以删除实例中的属性~(提到delete那要插一句~delete只能删除对象下的属性,不能删除变量和参数!)

       __proto__:事实上就是原型链指针!!

    prototype:上面说到这个是指向原型对象的

    constructor:每一个原型对象都包含一个指向构造函数的指针,就是constructor

    __proto__会指向上一层的原型对象,而上一层的结构依然类似,那么就利用__proto__一直指向Object的原型对象上!Object.prototype.__proto__ = null;表示到达最顶端。如此形成了原型链继承。

    1、B由A创建,必有B.__proto__ === A.prototype;

    2、A.prototype是原型对象,也是对象。

    3、Object是作为众多new出来的实例的基类

    4、Function是作为众多function出来的函数的基类

    5、构造函数的__proto__(包括Function.prototype和Object.prototype)都指向Function.prototype

    6、原型对象的__proto__都指向Object.prototype

    7、Object.prototype.__proto__指向null

    由上面7条规则,可容易理解下面关于原型链指针和原型对象的关系。

    //代码1
    function People(){}
    var p = new People()
    1 p.__proto__ === People.prototype 
    //People函数创建了对象 p,所以People.prototype === p.__proto__;
    2 People.__proto__ === Function.prototype
    //People 作为对象的角色被函数Function创建,
    所以 Function.prototype === People.__proto__
    3 People.prototype.__proto__ === Object.prototype
    //Object函数创建了People.prototype对象,
    所以Object.prototype === People.prototype.__proto__;
    4 Function.prototype === Function.__proto__  
    //任何函数都是 Function 创建,所以Function 创建了 Function,
    所以 Function.prototype === Function.__proto__;
    5 Function.prototype === Object.__proto__ 
    //Object 也是函数。所以Function创建了Object,
    所以 Function.prototype === Object.__proto__ ;         
    6 Function.prototype.__proto__ === Object.prototype 
    //Function.prototype 是普通对象,普通对象是由Object创建的,
    所以 Function.prototype.__proto__ === Object.prototype
    7 Function instanceof Object
    //instanceof 的作用是判断一个对象是不是一个函数的实例。
    obj instanceof fn, 实际上是判断fn的prototype是不是在obj的原型链上
  • 相关阅读:
    ssm 在不同的数据库中进行切换(开启事物禁用)
    引入xfire-all.jar后导致sping配置异常
    单点登录cas的最简单使用
    win10下cmd命令不能用
    前端json 两个重要的方法
    maven 工程下第三方jar 包的引入和打包 war
    idea 中main 方法不能运行
    从sqlServer 分页查询谈${}和#{}
    can与could区别
    线程同步与异步区别
  • 原文地址:https://www.cnblogs.com/jwenming/p/14437864.html
Copyright © 2020-2023  润新知