JS-OOP篇

什么是OOP

OOP ,即面向对象编程,是基于原型,通过封装、继承、多态组织代码的面向对象编程范式

JS的OOP本质

通过原型链实现对象间的属性 / 方法共享与委托

何为原型

原型(prototype)是函数的一个属性 ,它是一个对象,用于存储所有实例共享的属性和方法;实例对象通过 __proto__ 指向该原型。每个实例对象都有其对应的唯一原型,一个原型可对应很多实例对象

原型链

原型链是实例对象与原型对象之间的链式关联(实例 → 构造函数原型 → 父构造函数原型 → ... → null)。通过原型链可共享向上查找并共享父原型的属性和方法

如上图所示:

  • 所有对象的原型链最终都会指向 Object.prototype (除 Object.prototype 自身,其 __proto__null),并以null结束
  • 当外部访问一个属性/方法时,先从当前的原型查找,如果找到则用当前原型即可,如果未找到则沿着原型链向上进行查找,找到直接拿过来用,实现"共享"

Notice:与Java的类实现本质不同,Java是通过父类复制属性和方法到子类中实现继承连接,属于"向下共用";而JS是通过原型链来实现对象之间的连接,属于"向上共用"

如何实现对象连接原型

构造函数

步骤:

  1. 在子构造函数中通过 Parent.call(this, 参数) 调用父构造函数,目的是继承父构造函数中的实例属性 (而非 "实现 this 的指向"),this 本身已指向子实例,call 的作用是绑定父构造函数的 this 为子实例。
  2. 填写相应的属性和方法
  3. 连接原型:连接父原型和子原型------子类构造函数.prototype = Object.creat(父类构造函数.prototype)
  4. 将子构造函数原型的constructor重置为自身
  5. 通过new关键字创建一个实例对象

Notice:

  • 若想在子实例中新增一个新方法,则最好是在其原型上增加,好处是更加简洁,便于后续的实例也同样添加其方法
  • 获得原型的方法:实例.__proto__ 指向原型(英文的双下划线),即 构造函数.prototype === 实例.__proto__
  • 在方法内容书写的最后一般都return this便于实现方法链

ES6+class

步骤:

  1. 类比Java的类的实现模板,创建一个class,并用extends创建原型链
  2. 在构造函数constructor中使用super来实现this的指向为子类实例
  3. 然后再内部实现属性和方法 、

Notice:

  1. set/get方法
  • set方法:当方法为set 函数名 ...时分两种情况,当函数名与函数内部调用的属性名均不相等时,可直接用;反之,需要将类内所有调用的属性名都适当改变(一般使用假封装),避免无限迭代。使用set方法可以实现对值得验证和处理
  • get方法:当方法为get 函数名 ...时可直接用实例.函数名调用该方法(一般函数名就是属性名)
  1. 静态方法:在最前面添加static,该方法只能用类而不能用实例调用

OOP特性

封装

封装的目的是为了实现数据保护,避免直接被外部直接访问获取

真封装

共有属性/方法,直接正常写

私有属性/方法,在前面添加"#",若在构造函数中赋值私有属性,需要在类内部先声明

假封装

在属性/方法名前面添加"_"
_ 只是命名约定 (表示 "建议外部不要访问"),但无法真正阻止外部访问(仍可通过 obj._prop 读写),不属于 "封装",仅为开发者之间的约定。

继承

继承:实例属性、原型链+方法

构造函数

具体体现在"如何实现对象连接原型------构造函数"中的callObject.creat以及重置constructor

  • call 用于继承实例属性
  • Object.create 用于连接原型链(继承原型方法) ,两者结合才是完整的继承实现,缺一不可。

ES6+class

具体体现在"如何实现对象连接原型------ES6+class"中的superextends

  • super() 负责实例层面的继承(获取父类实例属性)。
  • extends 负责原型链层面的继承(共享原型方法);

Object.creat()

具体使用在"构造函数------步骤------连接原型"中
Object.create(proto) 的核心作用是创建一个以 proto 为原型的新对象,其主要用途是实现原型继承

多态

在JS中体现为原型链上的方法重写实现,即同一方法在不同对象上调用时表现出不同行为,以及动态类型检查 ,都体现并实现了同一接口,不同实现

最后

前端开发之路任重而道远,在未来仍有很多知识需要学习,小编也是一个初学者,让我们一起加油!如果这篇文章能帮到你的话,荣幸之至;如果有错误的话并指出来的话,小编将不胜感激。

相关推荐
子兮曰18 小时前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰19 小时前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万19 小时前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝19 小时前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋19 小时前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁20 小时前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄21 小时前
JavaScript 隐式全局变量解析
javascript
汉堡大王95271 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大1 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师1 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端