原型链涉及的概念有很多,不如举例来说明一下吧
    假如有一个普通对象 x={}, 则 x 会有一个隐藏属性 proto, 且

    1. x.__proto__ === Object.prototype

    则我们说 x 的原型是 Object.prototype, 在 Object.prototype 中有对象的公共方法, 比如 hasOwnProperty, isPrototypeOf 等

    再比如有一个普通数组 a=[], 则 a 有一个默认属性 proto, 且

    1. a.__proto__ === Array.prototype

    Array.prototype 也有一个隐藏属性 proto, 且

    1. Array.prototype.__proto__ === Object.prototype

    即 a 的原型是 Array.prototype,
    a 的原型的原型是 Object.prototype,
    通过隐藏属性proto形成了原型链

    原型链有什么用呢?
    原型链在没有 Class 的情况下实现「继承」。以 a ===> Array.prototype ===> Object.prototype 为例,我们说:

    1. a 是 Array 的实例,a 拥有 Array.prototype 里的属性
    2. Array 继承了 Object
    3. a 是 Object 的间接实例,a 拥有 Object.prototype 里的属性

    这样一来,a 就既拥有 Array.prototype 里的属性,又拥有 Object.prototype 里的属性。

    优点:
    简单、优雅。

    缺点:
    跟 class 相比,不支持私有属性。
    但 class 是 ES6 引入的,不被旧 IE 浏览器支持。

    指定原型的方法
    看起来只要改写 x 的隐藏属性 proto 就可以改变 x 的原型

    1. x.__proto__ = 原型

    但是这不是标准推荐的写法
    推荐的写法是

    1. const x = Object.create(原型) // x.__proto__ === 原型
    2. // 或
    3. const x = new 构造函数() // x.__proto__ === 构造函数.prototype