本文深入解析JavaScript中面向对象的三大核心特性:封装、继承与多态。详细对比call继承、原型链继承及寄生组合式继承等实现方式,阐述ES6 Class语法糖背后的原理。同时介绍函数重载机制、方法重写技巧,并总结单一职责、开放封闭等五大面向对象设计原则,帮助开发者构建更健壮、可复用的代码结构。
面向对象三大特性概述
面向对象编程包含三大核心特性:封装、继承和多态。
封装的实现与作用
封装是面向对象的基础特征之一,也是类与对象概念的关键属性。
封装旨在将客观事物抽象为类,并限制外部对类内部数据和方法的访问权限,仅允许受信任的类或对象进行操作,从而隐藏敏感信息。简单来说,类是一个封装了数据及操作代码的逻辑实体。在对象内部,部分代码或数据可设为私有,禁止外部直接访问。这种机制为内部数据提供了不同级别的安全保护,防止程序中无关部分意外修改或错误调用对象的私有内容。
在Vue项目中,常通过混入(Mixin)机制提取公共代码并注入到各个需要的组件中,从而简化代码结构。
此外,可将通用方法或工具函数进行封装,以实现代码复用,提升代码简洁性。
继承机制详解
继承允许一个类型的对象获取另一个类型对象的属性与方法,支持层级分类概念。
继承使得子类无需重新编写原有类代码即可扩展其功能。通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。继承是从一般到特殊的演化过程。实现继承的方式主要包括“继承”(Inheritance)和“组合”(Composition)。具体实现分为两类:实现继承直接复用基类的属性和方法,无需额外编码;接口继承仅复用属性和方法名,但子类必须提供具体实现。
JavaScript中实现继承有多种方式。
Call继承
Call继承
function a (){
this.c=111
}
function b(){
a.call(this)
}
let d = new b()
console.log(d.c) // 111
上述代码示例展示了函数b通过改变父类函数的this指向,从而继承函数a的私有属性。
原型继承
原型继承
function a (){
this.c=111
}
a.prototype.getName=function(){
return '你好'
}
function b(){
// a.call(this)
}
b.prototype=new a()
b.constructor=b
let d = new b()
console.log(d.c) // 111
console.log(d.getName()) // 你好
原型继承通过将父类实例赋值给子类的原型对象,使子类既能继承父类的私有属性,也能继承私有方法。
寄生组合继承
寄生组合继承
function a (){
this.c=111
}
a.prototype.getName=function(){
return '你好'
}
function b(){
a.call(this)
}
b.prototype=Object.create(a.prototype)
let d = new b()
console.log(d.c) // 111
console.log(d.getName()) // 你好
寄生组合继承结合使用call继承来改变this以实现私有属性的继承,同时利用Object.create实现公有属性的继承。
ES6 Class继承
ES6 Class继承
class parent{
constructor(){
this.a=1
}
name(){
return 2
}
}
class child extends parent{
}
let A = new child()
console.log(A.a) // 1
console.log(A.name()) // 2
通过关键字extends实现子类对父类私有和公有成员的继承。需注意,若子类定义了constructor,则必须调用super(),否则会导致报错。
class parent{
constructor(){
this.a=1
}
name(){
return 2
}
}
class child extends parent{
constructor(){
// 这里不写super会报错,报错信息如下
}
}
// ncaught ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor at new child
多态指同一类实例的不同方法在不同情境下呈现不同表现形式。
多态机制允许具有不同内部结构的对象共享相同的外部接口。这意味着尽管具体操作因对象而异,但可通过公共类以相同方式调用这些操作。
重载
函数重载指在同一作用域内,存在一组函数名相同但参数列表不同的函数,称为重载函数。重载通常用于命名功能相似的函数,减少函数名数量,避免命名空间污染,显著提升程序可读性。
- JavaScript通过函数名定位对应的函数对象。
- 随后根据函数定义时的参数与调用时表达式参数列表按顺序匹配,多余参数被忽略,不足参数按undefined处理。
- 最后执行函数代码。
多态与重载机制
// 可以跟据arguments个数实现重载
function add() {
var sum = 0 ;
for ( var i = 0 ; i < arguments.length; i ++ ) {
sum += arguments[i];
}
return sum;
}
console.log(add()) // 0
console.log(add(1,2)) // 3
console.log(add(1,2,3)) // 6
重写
“实例中的指针仅指向原型,而不是指向构造函数”。
“重写原型对象切断了现有原型与任何之前已经存在的对象实例之间的关系;它们引用的仍然是最初的原型”。
方法重写原理
var parent = function(name,age){
this.name = name;
this.age = age;
}
parent.prototype.showProper = function(){
console.log(this.name+":"+this.age);
}
var child = function(name,age){
parent.call(this,name,age);
}
// inheritance
child.prototype = Object.create(parent.prototype);
// child.prototype = new parent();
child.prototype.constructor = child;
// rewrite function
child.prototype.showProper = function(){
console.log('I am '+this.name+":"+this.age);
}
var obj = new child('wozien','22');
obj.showProper();
上述代码通过寄生组合继承方式,实现子类对父类私有属性的继承以及公有属性的继承,并重写了父类的showProper方法。
面向对象五大设计原则
面向对象设计包含五大原则。
- 单一职责原则
- 开放封闭原则
- 替换原则
- 依赖原则
- 接口分离原则
单一职责原则
单一职责原则指一个方法只负责一件事。例如当前项目结构即遵循了该原则。
开放封闭原则
开放封闭原则强调对修改关闭,对扩展开放。
class a {
add(){
return 11
}
}
class b extends a{
}
let c = new b()
console.log(c.add()) // 111
可通过extends继承父类,并在子类b中修改add函数,从而实现对修改关闭、对扩展开放。
以上为本文全部内容,希望对学习有所帮助,欢迎支持本站。