知识要点
- 了解JS的面向对象
- 了解JS中的原型及原型链
- 一些常见的问题
补充知识点
对象的理解
- 对象是对单个物体的简单抽象,它是一个容器,封装了一些属性和方法
// 简单对象
const obj = {
name: '11',
age: 20
}
// 函数对象
function Obj() {
this.name = '11';
this.age = 20;
}
复制代码
构造函数 – 生成对象
- JS 本质不是基于类,而是基于构造函数 + 原型链
function Person() {
this.name = '11';
this.age = 20;
}
const person = new Person()
复制代码
Person本质就是构造函数
- 函数体内的 this, 代表生成的实例对象
- 通过 new 实例化对象
- 构造函数必须实例化
- 如果构造函数不初始化使用,如何进行兼容
function Person() {
const isClass = this instanceof Person;
if(!isClass) {
return new Person();
}
this.name = '11';
this.age = 20;
}
const person = Person()
复制代码
什么是 new,new做了哪些
- 创建一个空对象,作为返回的对象实例
- 将生成的空对象的原型对象(__proto__)指向构造函数的 prototype 属性
- 将当前实例对象赋给内部 this
- 执行构造函数内部初始化代码
什么是 constructor
- 每个对象创建时会自动拥有一个构造函数属性 constructor
- constructor 属性继承自原型对象,指向构造函数的引用
原型对象
- 构造函数用来初始化创建对象的函数,自动给构造函数赋予一个 prototype 属性,该属性实际等于实例对象的原型对象(__proto__)
实例对象
- 每个对象中都有一个 __proto__
- 每个实例对象都有个 constructor 属性
- constructor 由继承而来,并指向当前构造函数
继承
在原型对象上的所有属性和方法,都能被实例所共享
通过原型链继承
// 动物类
function Animal() {
this.name = 'dog'
}
Animal.prototype.getName = function() {
return this.name
}
// 狗类
function Dog() {}
// 继承Animal类
Dog.prototype = new Animal()
Dog.prototype.constructor = Dog
const animal = new Dog()
复制代码
上述继承的实现方式,本质是重写原型对象,将父对象的属性和方法作为子对象原型对象上的属性和方法
通过原型链继承有什么缺点
- 父类属性一旦赋值给子类的原型属性,该属性属于子类的共享属性
- 实例化子类时不能向父类传参
通过构造函数继承
- 在子类构造函数内部调用父类构造函数
function Animal(arg) {
this.name = 'dog'
}
Animal.prototype.getName = function() {
return this.name
}
// 子类
function Dog(arg) {
Animal.call(this, arg)
}
const animal = new Dog()
复制代码
解决了共享属性和传参问题,但是原型链上的共享方法无法被继承
组合继承
通过组合继承可以解决上述问题
function Animal(arg) {
this.name = 'dog'
}
Animal.prototype.getName = function() {
return this.name
}
// 子类
function Dog(arg) {
Animal.call(this, arg)
}
Dog.prototype = new Animal()
Dog.prototype.constructor = Dog
// Dog继承Animal
const dog = new Dog()
复制代码
缺点:组合继承无论在何种场景,都会调用两次父类构造函数,一次在初始化子类原型时,一次在子类构造函数内部call父类的时候
寄生组合继承
寄生组合继承可以解决上述问题
// 子类
function Dog(arg) {
Animal.call(this, arg)
}
Dog.prototype = Object.create(Animal.prototype)
Dog.prototype.constructor = Dog
复制代码
多重继承
// 动物类
function Animal(arg) {
this.name = 'bird'
}
Animal.prototype.getName = function() {
return this.name
}
// 技能类
function Skill(arg) {
this.name = 'fly'
}
Skill.prototype.getSkill = function() {
return this.name
}
// 鸟类
function Bird(arg) {
Animal.call(this, arg)
Skill.call(this, arg)
}
Bird.prototype = Object.create(Animal.prototype)
Object.assign(Bird.prototype, Skill.prototype)
Bird.prototype.constructor = Bird
const bird = new Bird()
复制代码
流程图
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END