【基础类】—面向对象类系统性学习

一、类与实例

1. 类的声明

  1. 构造函数模拟一个类
javascript 复制代码
function Animal () {
	this.name = 'name'
}
  1. ES6 Class声明
javascript 复制代码
//  类名
class Animal2 {
    // 构造函数
	constructor () {
		// 属性
		this.name = name
	}
}

2.生成实例

  1. 通过 new 实例化一个类
javascript 复制代码
console.log(new Animal(), new Animal2())
// PS: 类没有参数时,可以省略括号
console.log(new Animal, new Animal2)

二、类与继承

1.如何实现继承

  1. 借助构造函数实现继承
javascript 复制代码
function Parent1 () {
	this.name = 'parent1';
}
function Child1 () {
	// call/ apply 改变函数运行的上下文, Parent1再子类的构造函数执行,同时修改了父类this的指向到child内部,从而导致父类的属性都会挂载到子类这个实例上
	Parent1.call(this);
	this.type ='child1'
}

console.log(new Child1())
Child1 {name: 'parent1', type: 'child1'}

缺点: Parent1的原型上的属性和方法,并没有被child所继承。

javascript 复制代码
Parent1.prototype.say = function () {
	console.log('你好')
}
Child1 下没有say方法

总结:只实现了部分继承,如果父类的属性都在构造函数里面,完全可以实现继承,如果父类的原型对象上还有方法或属性,那么子类是无法拿到方法或属性的

  1. 借助原型链实现继承
javascript 复制代码
function Parent2 () {
	this.name = 'parent2';
}
function Child2 () {
	this.type = 'child2'
}
Child2.prototype = new Parent2();
// prototype 是子类构造函数的一个属性,这个属性是一个对象,这个对象是可以任意赋值的,这个对象赋值了一个Parent2的实例
// new Child2() 生成一个新的实例, new Child2.__proto__ === Child2.prototype === new Parent2()
console.log(new Child2())
javascript 复制代码
function Parent2 () {
	this.name = 'parent2';
    this.play = [1,2,3]
}
function Child2 () {
	this.type = 'child2'
}
Child2.prototype = new Parent2();

var s1 = new Child2();
var s2 = new Child2();
console.log(s1.play, s2.play)
(3) [1, 2, 3] (3) [1, 2, 3]
s1.play.push(4);
console.log(s1.play, s2.play)
(4) [1, 2, 3, 4] (4) [1, 2, 3, 4]

缺点:因为原型链的原型对象是共用的,所以修改原型对象的属性,其他实例也会受影响

javascript 复制代码
s1.__proto__  === s2.__proto__
true
  1. 组合方式继承
javascript 复制代码
function Parent3 () {
	this.name = 'parent3'
	this.play = [1,2,3]
}
function Child3 () {
	Parent3.call(this);
	this.type = 'child3'
}
Child3.prototype = new Parent3();
var s3 = new Child3();
var s4 = new Child3();
s3.play.push(4)
console.log(s3.play, s4.play)
(4) [1, 2, 3, 4] (3) [1, 2, 3]
缺点:Parent3.call(this) 和 new Parent3() , Parent3 执行了2次
  1. 组合方式继承优化1
javascript 复制代码
function Parent4 () {
	this.name = 'parent4'
	this.play = [1,2,3]
}
function Child4 () {
	Parent4.call(this);
	this.type = 'child4'
}
Child4.prototype = Parent4.prototype;
var s5 = new Child4();
var s6 = new Child4();
s5.play.push(4)
console.log(s5.play, s6.play)
// (4) [1, 2, 3, 4] (3) [1, 2, 3]
// s5 是否Child4的实例, s5 是否是Parent4的实例
console.log(s5 instanceof Child4, s5 instanceof Parent4)
// true true
s5.constructor
ƒ Parent4 () {
	this.name = 'parent4'
	this.play = [1,2,3]
}

缺点:无法区分构造函数的实例,是由父类创造的还是有子类创造的

  1. 组合方式继承优化2
javascript 复制代码
function Parent5 () {
	this.name = 'parent5'
	this.play = [1,2,3]
}
function Child5 () {
	Parent5.call(this);
	this.type = 'child5'
}
// 通过中间对象的方法,把父类和子类区分开
Child5.prototype = Object.create(Parent5.prototype)
Child5.prototype.constructor = Child5
var s7 = new Child5();
console.log(s7 instanceof Child5, s7 instanceof Parent5)
console.log(s7.constructor)
true true
ƒ Child5 () {
	Parent5.call(this);
	this.type = 'child5'
}

2.继承的几种方式

  1. 借助构造函数实现继承
  2. 借助原型链实现继承
  3. 借助构造函数和原型链实现组合继承
相关推荐
爱生活的苏苏3 小时前
elementUI 表单验证-联动型校验
前端·javascript·elementui
一只小风华~5 小时前
Vue Router 路由元信息(meta)详解
前端·javascript·vue.js
*且听风吟5 小时前
html 实现鼠标滑动点亮横轴
前端·javascript·html
速易达网络7 小时前
Vue3 原生移动应用开发来了
前端·javascript·css
渣哥7 小时前
别再乱用了!Spring AOP 与 AspectJ 的区别比你想的复杂
javascript·后端·面试
患得患失9497 小时前
【Turborepo】【Next】 Turborepo + Next.js 前后端精简搭建笔记(带官网)
开发语言·javascript·笔记
小谭鸡米花7 小时前
高德地图电子围栏/地图选区/地图打点
前端·javascript·vue.js
西瓜树枝8 小时前
解决 JS 大整数精度丢失?一文读懂 BigInt 的底层逻辑与实战规则
前端·javascript
刺客_Andy8 小时前
React 第四十六节 Router中useInRouterContext的使用详细介绍及注意事项
前端·javascript·react.js
刺客_Andy8 小时前
React 第四十四节Router中 usefetcher的使用详解及注意事项
前端·javascript·react.js