前端面试押题
  • HTML
    • 有哪些新标签?
    • SVG 的区别是什么?
    • 如何理解 HTML 中的语义化标签
  • CSS
    • 如何清除浮动?
    • CSS 选择器优先级如何确定?
    • BFC 是什么
    • 两种盒模型(box-sizing)的区别?
    • 如何实现垂直居中?
  • JavaScript 押题基础篇
    • new 做了什么?
    • JS 如何实现类?
    • JS 的闭包是什么?怎么用?
    • JS 如何实现继承?
    • JS 的立即执行函数是什么?
    • JS 的数据类型有哪些?
    • 原型链是什么?
    • 这段代码中的 this 是多少?
  • JavaScript 押题手写篇
    • 手写数组去重
    • 手写简化版 Promise
    • 手写 AJAX
    • 手写深拷贝
    • 手写节流 throttle、防抖 debounce
    • 手写发布订阅
    • 手写 Promise.all
  • DOM 押题
    • 请简述 DOM 事件模型
    • 手写可拖曳 div
    • 手写事件委托
  • HTTP 押题
    • 说说同源策略和跨域
    • POST 的区别有哪些?
    • TCP 三次握手和四次挥手是什么?
    • Session、Cookie、LocalStorage、SessionStorage 的区别
    • HTTP 缓存有哪些方案?
    • HTTPS 的区别有哪些?
    • HTTP/2 的区别有哪些?
  • React 押题
    • 什么是高阶组件 HOC?
    • React Hooks 如何模拟组件生命周期?
    • 你如何理解 Redux?
    • React 有哪些生命周期钩子函数?数据请求放在哪个钩子里?
    • React 如何实现组件间通信
    • 虚拟 DOM 的原理是什么?
    • Vue DOM diff 的区别?
    • DOM diff 算法是怎样的?
  • Node.js 押题
    • 浏览器里的微任务和任务是什么?
    • EventLoop 是什么?
    • koa.js 的区别是什么?
  • TypeScript 押题
    • JS 的区别是什么?有什么优势?
    • any、unknown、never 的区别是什么?
    • TS 工具类型 Partial、Required、Readonly、Exclude、Extract、Omit、ReturnType 的作用和实现?
    • interface 的区别是什么?
Powered by GitBook
On this page
  1. JavaScript 押题基础篇

原型链是什么?

大概念题,答题思路为大概念化成小概念(分割),抽象化成具体(举例)。

我的答题思路如下:

哦,原型链涉及到的概念挺多的,我举例说明一下吧。

假设我们有一个普通对象 x={},这个 x 会有一个隐藏属性,叫做 __?????__ ,这个属性会指向 Object.prototype ,即

x.__?????__ === Object.prototype // 原型

此时,我们说 x 的原型 是 Object.prototype,或者说 Object.prototype 是 x 的原型。

而这个 __?????__ 属性的唯一作用就是用来指向 x 的原型的。

如果没有 __?????__ 属性,x 就不知道自己的原型是谁了。

为什么我用问号来表示?因为这样你不容易晕。

接下来我来说说原型链,我还是举例说明吧。

假设我们有一个数组对象 a=[] ,这个 a 也会有一个隐藏属性,叫做 __?????__ ,这个属性会指向 Array.prototype ,即

a.__?????__ === Array.prototype

此时,我们说 a 的原型是 Array.prototype,跟上面的 x 一样。但又有一点不一样,那就是 Array.prototype 也有一个隐藏属性 __?????__ ,指向 Object.prototype ,即

// 用 x 表示 Array.prototype
x.__?????__ === Object.prototype

这样一来,a 就有两层原型:

  1. a 的原型是 Array.prototype

  2. a 的原型的原型是 Object.prototype

于是就通过隐藏属性 __?????__ 形成了一个链条:

a ===> Array.prototype ===> Object.prototype 

这就是原型链。

以上我对「原型链是什么」的回答。

怎么做:

看起来只要改写 x 的隐藏属性 __?????__ 就可以改变 x 的原型(链)

x.__?????__ = 原型

但是这不是标准推荐的写法,为了设置 x.__?????___,推荐的写法是

const x = Object.create(原型)
// 或
const x = new 构造函数() // 会导致 x.__?????__ === 构造函数.prototype

没错,JS 就是这么别扭。

解决了什么问题:

在没有 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 呗。但 class 是 ES6 引入的,不被旧 IE 浏览器支持。

建议熟读这篇文章:

PreviousJS 的数据类型有哪些?Next这段代码中的 this 是多少?

Last updated 3 years ago