• JavaScirpt中的原型,原型对象和原型链


    一.什么是原型呢? 

    我们创建每一个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象.(即prototype即为函数的原型该原型指向的是一个原型对象)

    二.什么是原型对象呢?

    • 我们创建每一个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象(即原型对象).而这个对象的用途是包含
       可以由特定类型的所有 实例 共享的属性和方法.(字面意思prototype就是通过调用构造函数而创建的实例对象的原型对象)
    • 使用原型对象的好处是可以让所有的对象实例(实例对象)共享他包含的所有的属性和方法
    • 需要特别注意的是原型对象的理解,只要创建一个函数,该函数就会创建一个prototype(原型)属性,这个属性指向函数的原型对象

    三.原型对象和原型的关系?

           __proto__是什么呢?
    • 这是每一个JavaScript对象(除了 null )都具有的一个属性,叫__proto__,这个属性会指向该对象的原型。
    • 当调用构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性即__proto__),指向构造函数的原型对象

      constructor是什么呢?

    • 在默认情况下,所有的原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针即(Person.prototype.constructor指向Person),而通过这个构造函数,我们可以继续为原型对象添加起他属性和方法

      通过一张图片展示他们之间的关系

      

     代码示例:

    //创建一个构造函数,并在构造函数的原型上添加一个name属性
    function Person(){
    }
    Person.prototype.name = "kebi"
    var person1 = new Person();
    console.log(person1.name) //kebi
    var perso2 = new Person();
    console.log(person2.name) //kebi
    console.log(person.__proto__ === Person.prototype); // true 他两个的关系也是完全相等的

    console.log(Person.prototype.constructor == Person) // true
    // 顺便学习一个ES5的方法,可以获得对象的原型
    console.log(Object.getPrototypeOf(person) === Person.prototype) // true
    //b.isPrototypeOf(a) 这个方法的意思是,a对象是否指向b对象
    Person.prototype.isPrototypeOf(person1) //true 因为person1中有一个__proto__属相指向原型对象(
    Person.prototype)
    Person.prototype.isPrototypeOf(person2)  //true   同理
     

    总结一下prototype和__proto__到底是什么关系呢?

    • 函数对象的prototype属性, 可以称之为显式原型属性(简称: 显式原型)
    • 实例对象的__proto__属性, 可以称之为隐式原型属性(简称: 隐式原型)
    • 原型对象: 也就是prototype属性和_proto__属性指向的对象

    四.什么是原型链? 

      1.原型的搜索机制

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

       代码例子: 

    function Person() {
    
    }
    
    Person.prototype.name = 'heyushuo';
    
    var person = new Person();
    
    person.name = 'kebi';
    console.log(person.name) // kebi
    
    delete person.name;
    console.log(person.name) //heyushuo

    在这个例子中,我们给实例对象 person 添加了 name 属性,当我们打印 person.name 的时候,结果自然为 kebi。

    但是当我们删除了 person 的 name 属性时,读取 person.name,从 person 对象中找不到 name 属性就会从 person 的原型也就是 person.__proto__ ,也就是 Person.prototype中查找 (原型对象中),幸运的是我们找到了 name 属性,结果为 heyushuo。

    但是万一还没有找到呢?原型的原型又是什么呢? ( 肯定需要一环一环地前行到原型链的末端才会停下来)

      最顶层为默认的原型

      所有的函数的默认原型都是Object的实例,所以默认原型都会包含一个内部指针,指向Object.prototype(默认原型的原型对象),这也真是所有自定义类型都会继承toString()/valueOf等默认的方法的根本原因.一直查到最顶层才算一个完整的原型链

    如图所示: 蓝色线为完整的原型链

    参考:Javascript:高级程序设计

     javascript深入之从原型到原型链(感觉原型和原型对象未分清楚)

     

  • 相关阅读:
    十分钟抢票千余张,黄牛的抢票软件是何原理
    常见乱码解决
    如何给程序中的变量起个好名字
    jsp自定义标签
    request.getHeader("Referer")理解【转载】
    mybatis学习笔记1--HelloMybatis
    Spring学习笔记14---bean的使用
    Spring学习笔记13--Autowire(自动装配)
    Spring 学习笔记12--AOP讲解
    Spring学习笔记11--Spring 自动装配 Bean
  • 原文地址:https://www.cnblogs.com/heyushuo/p/9860621.html
Copyright © 2020-2023  润新知