JavaScript里的原型链,也曾是一座大山

学过前端的小伙伴肯定都知道"原型"、"原型链"这些概念,也正如标题所言,它曾经是每个初学者的大山,特点如下:

  • 网上的解释太多且各不一样,导致概念难懂。
  • MDN里的官方解释,自己又看不下去,大部分一扫而过,导致看与不看,效果一样。
  • 牵扯的知识点琐碎且精细,加上工作中又不常用(甚至不用),导致对这个知识点总是模模糊糊。

作为曾经被迫害的一份子,我觉得有必要将这个知识点记录下来,给想要入门的前端小白,搭建一个比较清晰的思路,我们直接进入正题吧。

在此之前,我们今天讨论的内容,只针对引用数据类型。

你将收获

  • 理解什么是原型?
  • 理解什么是原型链?
  • 如何设置原型?
  • 如何区分属性是对象自有的,还是原型链上的?
  • 对象、原型、构造函数、constructor之间的关系

什么是原型?

JavaScript中所有的对象都有一个内置的对象,这个内置的对象就叫做"原型"。特别注意,在JavaScript中,只有 null、undefined 没有原型对象

如何访问原型对象呢?这个是要做出区分的,具体如下:

动手实践一下:

javascript 复制代码
function Person(name){
    this.name = name;
}

let p1 = {};
console.log('p1对象的原型对象:', p1.__proto__);

let p2 = new Person();
console.log('p2对象的原型对象:', p2.__proto__);

console.log('名字为Person的构造函数对应的原型对象:', Person.prototype);

原型链的定义

原型对象里也有原型,一直向上查找,直到为null。这一整条链路就叫做"原型链"。

如何遍历对象上的所有原型对象?我们以Date为例:

javascript 复制代码
let date = new Date(); 

do {
    date = Object.getPrototypeOf(date);
    console.log('date:', date);
}while(date);

如何设置原型对象?

这个方式就有很多,如下:

  • 如果你想给函数设置原型,那么你可以选择直接操纵 prototype属性。
  • 如果你想给字面量对象设置原型,那么你可以选择直接操纵 ._proto_ 属性。
  • 你也可以选择通过 Object.create(a) 方法来创建一个新对象b,这样b的原型对象就是a。
  • 你也可以选择new一个对象,那么这个 实例对象的原型 就是 构造函数的原型对象

如何区分属性是原型链上的还是自有的?

针对 对象属性来说,它的属性类型(string类型、还是symbol类型)、以及是否可被遍历 对于我们来说是很重要的。

获取对象属性的方式有很多,整理如下:

方法 说明
Object.keys 返回自身可遍历的字符串属性。
Object.getOwnPropertyNames 返回自身的字符串属性(无论是否可被遍历)。
Object.getOwnPropertySymbols 返回自身的symbol属性(无论是否可被遍历)。
Object.hasOwnProperty 此方法用于判断属性是否是对象自有的。
Reflect.ownKeys 这个API是最强大的,它可以返回对象自身的所有属性(无论是什么类型,无论是否可遍历)
for ... in ... 遍历 自身以及原型链上 可被遍历的字符串属性

相信有了上面的这张表,如何判断一个属性是否在原型链上,对你而言已不在话下。

对象、原型、构造函数、constructor之间的关系?

来用一张图收尾:

最后

好啦,本期的内容就分享到这里,如果上述过程中,有内容错误,请在评论区里指正,如果我的内容对您有帮助,还请给个5星好评,我们下期再见啦~~

相关推荐
京东零售技术1 分钟前
Taro on Harmony :助力业务高效开发纯血鸿蒙应用
前端·开源
前端大白话17 分钟前
救命!这10个Vue3技巧藏太深了!性能翻倍+摸鱼神器全揭秘
前端·javascript·vue.js
嘻嘻嘻嘻嘻嘻ys19 分钟前
《Vue 3全栈架构实战:Vite工程化、Pinia状态管理与Nuxt 3深度解析》
前端·后端
前端大白话21 分钟前
前端人必看!10个JavaScript“救命”技巧,让你告别加班改Bug
前端·javascript·程序员
Rudon滨海渔村27 分钟前
【Tauri】桌面程序exe开发 - Tauri+Vue开发Windows应用 - 比Electron更轻量!8MB!
javascript·electron·tauri·桌面应用
cg501731 分钟前
Vue回调函数中的this
前端·javascript·vue.js
前端太佬33 分钟前
从零到一实现扫码登录:一个前端菜鸟的踩坑实录
前端·javascript·架构
yuanmenglxb200444 分钟前
微信小程序核心技术栈
前端·javascript·vue.js·笔记·微信小程序·小程序
爱编程的鱼44 分钟前
如何让 HTML 文件嵌入另一个 HTML 文件:详解与实践
前端·html
_09271 小时前
Vue 2 与 Vue 3 的核心区别及 Vue 3 新特性详解
前端