面向对象
逻辑迁移更加灵活,代码复用性高,高度的模块化
对象定义
是单个物体的简单抽象,
对象是个容器,封装了属性和方法
属性:对象的状态
方法:对象的行为
class Course{
teacher:'ddd',
leader:'aaa',
set:function(){
}
}
// 方法类
function Course(){
this.teacher = 'ddd';
this.leader = 'hhh';
this.set = function(){
}
}
构造函数--生成对象
表征一类物体的共同特征
js 本质上并不是基于类,而是基于构造函数 + 原型链
constructor + prototype
- 函数体内使用的 this,指向的所要生成的实例
- 生成对象用 new 来进行实例化
- 可以做初始化传参
问题:如果不做初始化,可以使用吗?---不能使用
问题2: 如果项目中需要使用,通常(不被外界感知)如何解决
function Course(){
const _isClass = this instanceof Course;
if(!_isClass){
return new Course()
}
//...
}
new
new 的时候做了什么?
- 创建了一个空对象,作为返回对象的实例
- 将生成空对象的原型对象指向了构造函数的 prototype 属性
- 将当前实例对象赋给了内部 this
- 执行构造函数初始化代码,constructor
问题:实例属性的影响
单个实例的属性的改变不影响其他属性
function Course(){
this.teacher = 'ddd';
this.leader = 'hhh';
}
constructor
constructor是什么?
- 每个对象在创建的时候,都会自动拥有一个构造函数 constructor
- constructor继承自原型对象,指向构造函数
追问:使用构造函数有没有问题?
构造函数的方法会存在于每一个生成的实例里面,导致资源上的浪费
原型对象
- 构造函数:用来初始化创建对象的函数,
自动给构造函数赋予一个属性 prototype ,该属性等于实例对象的原型对象 - 实例对象:根据原型对象创建出来的实例
每个对象都有一个proto,和 constructor
proto指向构造器的原型,constructor 指向构造器 - 原型对象:Course.prototype
所以为了避免,方法生成在每一个实例里面,可以将方法挂载都实例对象的原型上
继承
原型链继承,
在原型对象的所有属性和方法,都能被实例所共享
// Game 类
function Game(){
this.name = 'lol';
}
Game.prototype.getName = function(){
return this.name;
}
function LOL(){}
LOL.prototype = new Game();
LOL.prototype.construntor = LOL;
const game = new LOL();
// 重写原型对象,将父对象的属性方法,作为子对象原型对象的属性和方法
构造函数继承
function Game(arg){
this.name = 'name';
this.age = 'age';
}
Game.prototype.getName = function(){
return this.name;
}
function LOL(arg){
Game.call(this,arg);
}
const game3 = new LOL('arg')
问题:
原型链上的方法想继承,如何继承?
组合继承
function Game(arg){
this.name = 'name';
this.age = 'age';
}
Game.prototype.getName = function(){
return this.name;
}
function LOL(arg){
Game.call(this,arg);
}
LOL.prototype = new Game();
LOL.prototype.construntor = LOL;
const game3 = new LOL('arg')
组合继承有没有缺点?问题:无论如何,都会调用两次父类的构造函数
- 初始化子类原型时
- 子类调用函数内部 call 父类的时候
解决方案:寄生组合继承
function Game(arg){
this.name = 'name';
this.age = 'age';
}
Game.prototype.getName = function(){
return this.name;
}
function LOL(arg){
Game.call(this,arg);
}
LOL.prototype = Object.create(Game.prototype);
LOL.prototype.construntor = LOL;
const game3 = new LOL('arg')