美文网首页
面向对象(三)

面向对象(三)

作者: 懂会悟 | 来源:发表于2020-09-08 08:35 被阅读0次

1、构造函数、原型和实例的关系

  • 每个构造函数都有一个原型对象, 通过prototype指针指向该原型对象.
  • 原型对象都包含一个指向构造函数的指针, 通过constructor指针, 指向构造函数
  • 而实例都包含一个指向原型对象的内部指针, 该内部指针我们通常使用proto来描述.

2、原型链

  • 我们可以通过Person.prototype = {}的方式来重写原型对象.
  • 假如, 我们后面赋值的不是一个{}, 而是另外一个类型的实例, 结果会是怎么样呢?
  • 显然,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型对象中也包含着一个指向另一个构造函数的指针。
  • 假如另一个原型对象又是另一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实例与原型对象的链条。这就是所谓原型链的基本概念。

// 1.创建Animal的构造函数
function Animal() {
    this.animalProperty = "Animal"
}
// 2.给Animal的原型中添加一个方法
Animal.prototype.animalFunction = function () {
  console.log(this.animalProperty)
}

// 3.创建Person的构造函数
function Person() {
    this.personProperty = "Person"
}

// 4.给Person的原型对象重新赋值
Person.prototype = new Animal()

// 5.给Person添加属于自己的方法
Person.prototype.personFunction = function () {
  console.log(this.personProperty)
}

// 6.创建Person的实例
var person = new Person()
person.animalFunction()
person.personFunction()

3、实例属性搜索

当以读取模式访问一个实例属性时,首先会在实例中搜索该属性。如果没有找到该属性,则会继续搜索实例的原型。在通过原型链实现继承的情况下,搜索过程就得以沿着原型链继续向上。
在找不到属性或方法的情况下,搜索过程总是要一环一环地前行到原型链末端才会停下来。

参照上面的例子

  • 第一步, 在person实例中搜索, 搜索到直接返回或者调用函数. 如果没有执行第二步.
  • 第二步, 在Person的原型中搜索, Person的原型是谁? Animal的实例. 所以会在Animal的实例中搜索, 无论是属性还是方法, 如果搜索到则直接返回或者执行. 如果没有, 执行第三步.
  • 第三步, 在Animal的原型中搜索, 搜索到返回或者执行, 如果没有, 搜索结束. (当然其实还有Object, 但是先不考虑)

4、判断实例原型

  • instanceof:只要是实例与原型链中出现过的构造函数,结果就会返回true。
  • isPrototypeOf:只要是原型链中出现过的原型,都可以说是该原型链所派生的实例的原型,因此isPrototypeOf()方法也会返回true
// instanceof
console.log(person instanceof Object) 
// true
console.log(person instanceof Animal)
// true
console.log(person instanceof Person)
// true

// isPrototypeOf
console.log(Object.prototype.isPrototypeOf(person))
// true
console.log(Animal.prototype.isPrototypeOf(person))
// true
console.log(Person.prototype.isPrototypeOf(person))
// true

5、原型链模式的问题

  • 原型链存在最大的问题是关于引用类型的属性.
  • 在创建子类型的实例时,不能向父类型的构造函数中传递参数,这就导致实例继承的属性都一致
function Person() {
  this.personProperty = "Person"
}

Person.prototype = new Animal()

Person.prototype.personFunction = function () {
  console.log(this.personProperty)
}

var person1 = new Person()
var person2 = new Person()

console.log(person1.colors) 
// red,green
console.log(person2.colors) 
// red,green
person1.colors.push("blue")
console.log(person1.colors) 
// red,green,blue
console.log(person2.colors) 
// red,green,blue

6、组合继承

基于原型链的问题我们可以使用组合继承来解决

  • 组合继承就是发挥原型链和经典继承各自的优点来完成继承的实现.
  • 使用原型链实现对原型属性和方法的继承.
  • 通过经典继承实现对实例属性的继承, 以及可以在构造函数中传递参数.
// 1.创建构造函数的阶段
// 1.1.创建Animal的构造函数
function Animal(age) {
  this.age = age
  this.colors = ["red", "green"]
}

// 1.2.给Animal添加方法
Animal.prototype.animalFunction = function () {
  console.log("Hello Animal")
}

// 1.3.创建Person的构造函数
function Person(name, age) {
  Animal.call(this, age)
  this.name = name
}

// 1.4.给Person的原型对象重新赋值
Person.prototype = new Animal(0)

// 1.5.给Person添加方法
Person.prototype.personFunction = function () {
  console.log("Hello Person")
}

// 2.验证和使用的代码
// 2.1.创建Person对象
var person1 = new Person("Tom", 18)
var person2 = new Person("Jury", 30)

// 2.2.验证属性
console.log(person1.name + "-" + person1.age)
console.log(person2.name + "-" + person2.age)

// 2.3.验证方法的调用
person1.animalFunction() 
// Hello Animal
person1.personFunction() 
// Hello Person

// 2.4.验证引用属性的问题
person1.colors.push("blue")
console.log(person1.colors) 
// red,green,blue
console.log(person2.colors) 
// red,green

相关文章

  • 面向对象

    面向对象:OOP 面向对象三大特性

  • Java学习day-07:面向对象

    一、面向过程和面向对象 1.面向对象与面向过程的区别: 面向对象具有三大特征;封装,继承,多态;面向对象与面向过程...

  • Java 工程师成神之路 | 2019正式版

    摘要:什么是面向对象 基础篇 01面向对象 → 什么是面向对象 面向对象、面向过程 面向对象的三大基本特征和五大基...

  • Java从入门到入坑(基础篇)

    01:面向对象 1:什么是面向对象 面向对象,面向过程 面向对象的三大基本特征和五大基本原则 三大特性:封装,继承...

  • 面向对象编程

    面向对象编程 一、面向对象和面向过程 二、类和对象 三、内存图 四、构造方法 五、关键字 六、面向对象的三大特征 ...

  • JS面向对象精要(二)_函数

    JS面向对象精要(一)_原始类型和引用类型JS面向对象精要(二)_函数JS面向对象精要(三)_理解对象JS面向对象...

  • JS面向对象精要(三)_理解对象

    JS面向对象精要(一)_原始类型和引用类型JS面向对象精要(二)_函数JS面向对象精要(三)_理解对象JS面向对象...

  • JS面向对象精要(四)_构造函数和原型对象

    JS面向对象精要(一)_原始类型和引用类型JS面向对象精要(二)_函数JS面向对象精要(三)_理解对象JS面向对象...

  • JS面向对象精要(五)_继承

    JS面向对象精要(一)_原始类型和引用类型JS面向对象精要(二)_函数JS面向对象精要(三)_理解对象JS面向对象...

  • 第七篇 面向对象编程

    一、复习 二、time模块的补充 三、面向对象 四、初始面向对象和类 五、面向对象之间的交互 六、面向对象的组合 ...

网友评论

      本文标题:面向对象(三)

      本文链接:https://www.haomeiwen.com/subject/jronsktx.html