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

最后

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

相关推荐
北海-cherish4 分钟前
Wouter 和 React Router的区别
前端·react.js·前端框架
醉方休6 分钟前
TensorFlow.js高级功能
javascript·人工智能·tensorflow
郝学胜-神的一滴13 分钟前
深入理解前端 Axios 框架:特性、使用场景与最佳实践
开发语言·前端·程序人生·软件工程
炒香菇的书呆子23 分钟前
基于Amazon S3设置AWS Transfer Family Web 应用程序
javascript·aws
!chen1 小时前
学习 React 前掌握 JavaScript 核心概念
javascript·学习·react.js
笨笨狗吞噬者1 小时前
【uniapp】小程序端实现分包异步化
前端·微信小程序·uni-app
Filotimo_1 小时前
2.CSS3.(1).html
前端·css
YAY_tyy1 小时前
【JavaScript 性能优化实战】第五篇:运行时性能优化进阶(懒加载 + 预加载 + 资源优先级)
前端·javascript·性能优化
1024小神1 小时前
flutter 使用dio发送本地https请求报错
前端
正义的大古1 小时前
OpenLayers地图交互 -- 章节七:指针交互详解
前端·javascript·vue.js·openlayers