原型和原型链

原型 和 原型链

        + 原型: 每个函数天生自带的 prototype 对象数据类型

          => 作用: 由构造函数向 原型上 添加方法, 提供给该构造函数的所有实例使用

          => 为了解决构造函数将方法书写在构造函数体内时造成的资源浪费

        + 原型链:

          => 概念: 用 __proto__ 串联起来的对象链状结构

          => 作用: 为了对象访问机制服务(当你访问一个对象成员的时候, 为你提供一些服务)

          => 注意: 只是 __proto__ 串联起来的对象链状结构, 千万不要往 prototype 上靠

概念:

        1. 每一个函数天生自带一个属性叫做 prototype, 是一个对象数据类型

        2. 每一个对象天生自带一个属性叫做 __proto__, 指向所属构造函数的 prototype

        3. 任何一个对象, 如果没有准确的构造函数, 那么看做是 Object 的实例

          => 只要是一个单纯的对象数据类型, 都是内置构造函数 Object 的实例

万物皆对象

        + 在 JS 内, 任何一个数据类型其实都是对象

        + 函数也是一个对象, 数组也是一个对象, 正则也是一个对象, ...

          => 是对象, 就可以存储 键值对

        + 以函数为例

          => 当你书写完毕一个函数的时候

          => 此时 函数数据类型 出现了, 同时该函数名也是一个对象数据类型

问题1: p1 身上的 __proto__ 是谁 ?
        => 因为 p1 是 Person 的时候
        => 根据 概念1 得到, p1.__proto__ 指向所属构造函数的 prototype

      问题2: Person 的 __proto__ 是谁 ?
        => Person 是一个构造函数, 同时也是一个函数, 同时也是一个对象
        => 只要是对象就会有 __proto__ 属性
        => JS 内有一个内置构造函数叫做 Function, 只要是函数, 就看做 Function 的实例
        => 任何一个函数数据类型所属的构造函数都是 Function
        => Person 看做是 Function 的实例
        => Person 所属的构造函数就是 Function
        => Person.__proto__ 指向 Function.prototype

      问题3: Person.prototype 的 __proto__ 是谁 ?
        => Person.prototype 是函数天生自带的一个对象数据类型
        => 只要是对象就会有 __proto__ 属性
        => JS 内有一个内置构造函数叫做 Object, 只要是单纯的对象, 都是 Object 的实例
        => Person.prototype 是一个天生的对象数据类型, 并且是一个单纯的对象数据类型
        => 把 Person.prototype 看做是 Object 的实例
        => Person.prototype 的 __proto__ 就是 Object.prototype

      问题4: Function 的 __proto__ 是谁 ?
        => Function 是一个构造函数, 同时也是一个函数, 同时也是一个对象
        => 只要是对象就会有 __proto__ 属性
        => JS 内有一个内置构造函数叫做 Function, 只要是函数就是 Function 的实例
        => Function 自己本身是一个内置构造函数, 本身也是一个函数
        => Function 自己是自己的实例, 自己是自己的构造函数
        => 在 JS 内管 Function 叫做顶级函数
        => Function.__proto__ 就是 Function.prototype

      问题5: Function.prototype 的 __proto__ 是谁 ?
        => Function.prototype 是函数天生自带的一个对象数据类型
        => 只要是对象就会有 __proto__ 属性
        => Function.prototype 是一个天生的对象数据类型, 并且是一个单纯的对象数据类型
        => 把 Function.prototype 看做是 Object 的实例
        => Function.prototype 的 __proto__ 就是 Object.prototype

      问题6: Object 的 __proto__ 是谁 ?
        => Object 是一个构造函数, 同时也是一个函数, 同时也是一个对象
        => 只要是对象就会有 __proto__ 属性
        => Object 也是一个函数, 只要是函数就是 Function 的实例
        => Object 这个内置函数所属的构造函数依旧是 Function
        => Object.__proto__ 就是 Function.prototype

      问题7: Object.prototype 的 __proto__ 是谁 ?
        => Object.prototype 势函数天生自带的一个对象数据类型
        => 只要是对象就会有 __proto__ 属性
        => 在 JS 内, Object 是顶级对象, Object.prototype 是顶级原型
        => Object.prototype 是唯一一个没有 __proto__ 的对象数据类型
        => Object.prototype 的 __proto__ 是 null


    function Person(name, age, gender) {
      this.name = name
      this.age = age
      this.gender = gender
    }

    Person.prototype.sayHi = function () { console.log('hello world') }

    const p1 = new Person('Jack', 18, '男')

    console.log(p1)

 


    // 问题1证明
    console.log(p1.__proto__ === Person.prototype)

    // 问题2证明
    console.log(Person.__proto__ === Function.prototype)

    // 问题3证明
    console.log(Person.prototype.__proto__ === Object.prototype)

    // 问题4证明
    console.log(Function.__proto__ === Function.prototype)

    // 问题5证明
    console.log(Function.prototype.__proto__ === Object.prototype)

    // 问题6证明
    console.log(Object.__proto__ === Function.prototype)

    // 问题7证明
    console.log(Object.prototype.__proto__)

prototype 和 __proto__ 有什么区别

    /*
      prototype 和 __proto__ 有什么区别
        1. 名字不一样
        2. 有可能指向同一个对象空间
          => prototype 前面主语一定是函数
          => __proto__ 前面的主语一定是对象
    */

    // 万物皆对象
    // 当函数创建完毕以后, 可以把 fn 当做一个对象名来使用
    function fn() {
      console.log('你好 世界')
    }

    // // 我把 fn 当做对象名来使用
    fn.a = 100

    // // 此时是把函数内 函数体 空间的代码执行掉
    // // 和函数对象空间内的数据没有任何关系
    fn()

    console.log(fn)
    console.dir(fn)


    // 数组同时也是一个对象空间
    var arr = [100, 200, 300, 400]

    // 完全可以把 arr 当做一个对象名来使用
    arr.age = 18

    // 当你遍历数组的时候, 只是遍历数组中的数组空间
    arr.forEach(item => {
      console.log(item)
    })

    console.log(arr)

最后总结

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值