kying-star的博客

vuePress-theme-reco kying-star的博客    2023
kying-star的博客

Choose mode

  • dark
  • auto
  • light
主页
指北
语言学习
AI
前端
后端
算法
杂项
github

kying-star的博客

7

Article

0

Tag

主页
指北
语言学习
AI
前端
后端
算法
杂项
github
  • js
    • 彻底了解This指针
    • 原型与原型链
    • AJAX
    • 防抖与节流
    • 闭包
    • 懒加载
    • 轮播图
    • js作用域
    • JS高阶函数和运行机制
  • css
  • vue
  • typescript
  • React
  • 前端新技术
  • 正则表达式
  • 浏览器

vuePress-theme-reco kying-star的博客    2023

原型与原型链

kying-star的博客

# 原型与原型链

# 知识背景

原型在平时工作中用得比较少, 但原型是 JavaScript 中的基础, 是构建大型应用, 框架不可或缺的一环, 是你在写代码时, 不知不觉就应用上了的一个最基础的知识.

# 原型

任何一个函数, 都拥有一个 prototype 属性, 它指向这个函数的原型对象, 如

function Foo() {}
console.log(Foo.prototype); // { constructor: f Foo(), __proto__: Object }
//浏览器显示的是__proto__指向的对象<prototype>: Object { … }

图表如下

mixureSecure

上图左边代表 Foo 函数, 它有一个 prototype 属性, 指向右侧这个原型对象, 每声明一个函数, 都会有这样的一个原型对象, 原型对象有一个 constructor 属性。constructor指向构造函数Foo本身。

我们来看Foo的实例化foo,任何构造函数的实例化都有__proto__属性,它指向构造函数的原型。

function Foo() {}
var foo = new Foo();
console.log(foo); //{__proto__:object}
//浏览器显示的是__proto__指向的对象<prototype>: Object { … }

图表如下

mixureSecure

foo 默认会有个 __proto__ 属性, 它也指向构造函数 Foo 的原型, 这就是 __proto__ 的作用, 即指向构造函数的原型。

然而Foo.prototype也具有__proto__属性,那么它又指向谁的原型呢?

所以让我们回到 Foo.prototype.__proto__, 来看看他的指向

图表如下

mixureSecure

上图的 Foo.prototype.__proto__ 指向 Object.prototype, 也就是说, 每个函数的原型, 都是 Object 的实例. 就好像每个函数的原型, 是由 new Object() 产生一样

以上就是关于原型的阐述, 如果看到这里似懂非懂, 建议反复看几遍, 注意文字与图片对应, 线条的指向, 看懂了再接着往下看.

# 原型链

原型链是 JavaScript 作者为了继承而设计的, 由上边的分析, const foo = new Foo() 语句, 其实是产生了一个链条的, 如下:

mixureSecure

我们在 new 出 foo 对象后, 并没有给 foo 对象添加任何方法, 但我们依然能从 foo 对象中调用 toString(), hasOwnProperty() 等方法. 这是为什么呢?

console.log(typeof foo.toString); // function
console.log(typeof foo.hasOwnProperty); // function

原因是, JavaScript 在设计之初, __proto__ 就是用来查找属性和方法的, 从上图的链条来看, 我们在 foo 这个对象中, 查找 toString 方法, 没找到, 就循着 foo.__proto__ 查找, foo.__proto__ 里也没有找到, 就循着 foo.__proto__.__proto__ 找, 诶这个时候找到了, 则调用, 如果还找不到, 就再往上找, 即 foo.__proto__._proto__._proto__, 这个时候值为 null, 查找结束.

这就是原型链, 我们也可以说, Foo 继承了 Object, 所以 foo 中能访问到 Object 的原型属性.