通过控制台学习原型链

前言

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

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

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

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

基础数据类型

众所众知基础数据类型有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的作用为向下传递。

相关推荐
秦jh_13 分钟前
【Linux】多线程(概念,控制)
linux·运维·前端
蜗牛快跑21326 分钟前
面向对象编程 vs 函数式编程
前端·函数式编程·面向对象编程
Dread_lxy27 分钟前
vue 依赖注入(Provide、Inject )和混入(mixins)
前端·javascript·vue.js
涔溪1 小时前
Ecmascript(ES)标准
前端·elasticsearch·ecmascript
用户3157476081351 小时前
成为程序员的必经之路” Git “,你学会了吗?
面试·github·全栈
榴莲千丞1 小时前
第8章利用CSS制作导航菜单
前端·css
奔跑草-1 小时前
【前端】深入浅出 - TypeScript 的详细讲解
前端·javascript·react.js·typescript
羡与2 小时前
echarts-gl 3D柱状图配置
前端·javascript·echarts
guokanglun2 小时前
CSS样式实现3D效果
前端·css·3d
咔咔库奇2 小时前
ES6进阶知识一
前端·ecmascript·es6