通过控制台学习原型链

前言

原型链是前端学习者绕不开的知识点,但坑爹的是平时的工作根本用不到,面试却又一定会问。

网上大多数教程的图和字太过抽象,背了忘,忘了背是常态。

在此记录一些我对原型链的理解,以及如何通过控制台快速了解复习原型链的方法。

本人水平有限,如有错误欢迎指正。

基础数据类型

众所众知基础数据类型有7种,而基础数据类型是没有原型链的,也就是说是什么就打印出来的就是什么,没有方法,没有原型,没有__proto__,也没有prototype。

但是,在控制台输入一些基础类型,如 true, 'string', 你会发现他们是有__proto__属性的。如下图所示:

这是因为当你访问基础数据类型的属性或方法时,JavaScript会临时将其包装为对应的对象类型,这个对象类型有原型链。这也是为什么我们可以直接调用字符串方法的原因,具体可以去了解下包装类型,在此不做过多解释。

引用数据类型

所有引用类型都有原型链。那么到底什么是原型链呢?

什么是原型链

个人简单粗暴的理解:原型链就是 通过 '__ proto __' 和 'prototype' 两个属性链接而成的一个链, 引用类型可以通过这两个属性访问到链上的所有属性。

'__ proto __' 和 'prototype' 的中文叫什么我也不知道,一般都叫原型, 原型对象,隐式原型,显式原型之类的,我至今也分不清楚,所以在此就直接用英文,反而不会弄混。

通过控制台看原型链

当在控制台输入一个引用类型时,如{}会发现在下面有个小箭头:

初看控制台输出的内容,有点像是对象中有个叫 Prototype的属性,但是输出一下,发现并不是这个意思:

在这个下面的属性,全是可以直接访问到的,其中就包括关键的__proto__属性:

可以发现打印出来的__proto__和外面观察到的[[Prototype]]一模一样,这就是原型链的关键:

当你访问一个引用对象不存在的属性时,他会在对象的__proto__属性中找同名属性。__proto__指向其构造函数的prototype属性。

可以做一个小实验去验证一下是否真的是一样的:

但是现在有个问题,当引用对象在__proto__里找不存在的属性时,其构造函数也是个对象,所以也有__proto__属性,那么就会一直向上传递,形成死循环。为了解决这个问题,js规定Object的__proto__为null, 因为所以引用对象本质上都是Object。

__ proto__找属性会向上传递,一层一层直到找到Object的__proto__,其值为null

一个例子

js中的继承就是通过原型链实现的。

在控制台中看看__proto__的搜索链:

js 复制代码
    class Father {
      sing () {
        console.log('I can sing')
      }
      dance () {
        console.log('I can dance')
      }

    }
    class Son extends Father {
      rap () {
        console.log('I can rap')
      }
    }
    let son = new Son()
    console.log('son:', son)
    console.log('son.__proto__:', son.__proto__)
    console.log('son.__proto__.__proto__', son.__proto__.__proto__)
    console.log('son.__proto__.__proto__.__proto__', son.__proto__.__proto__.__proto__)
    console.log('son.__proto__.__proto__.__proto__.__proto__', son.__proto__.__proto__.__proto__.__proto__)

总结:__ proto__ 的作用是向上搜索

再看看prototype的作用

js 复制代码
    Father.basketball = '篮球'
    console.log('son.basketball:', son.basketball) // undefined
    Father.prototype.basketball = '篮球'
    console.log('son.basketball:', son.basketball) // 篮球

总结:prototype的作用是向下传递

总结

面试官: 什么是原型链?

回答:原型链是js的继承实现机制,在js中所有引用类型都有一个__proto__属性,__proto__属性指向其构造函数的prototype属性,其构造函数的prototype也是引用类型,所以也有__proto__属性,直到搜索到了Object的__proto__属性为null才停止,因此形成了一个搜索链条,我们把这个搜索链条叫做原型链。可以通俗的理解为,__proto__的作用就是向上搜索,prototype的作用为向下传递。

相关推荐
豐儀麟阁贵5 分钟前
8.5在方法中抛出异常
java·开发语言·前端·算法
程序员念姐8 分钟前
软件测试系统流程和常见面试题
测试工具·面试
zengyuhan50335 分钟前
Windows BLE 开发指南(Rust windows-rs)
前端·rust
Bro_cat35 分钟前
Java基础
java·开发语言·面试
醉方休38 分钟前
Webpack loader 的执行机制
前端·webpack·rust
前端老宋Running1 小时前
一次从“卡顿地狱”到“丝般顺滑”的 React 搜索优化实战
前端·react.js·掘金日报
隔壁的大叔1 小时前
如何自己构建一个Markdown增量渲染器
前端·javascript
用户4445543654261 小时前
Android的自定义View
前端
WILLF1 小时前
HTML iframe 标签
前端·javascript
枫,为落叶1 小时前
Axios使用教程(一)
前端