美文网首页
面向对象类

面向对象类

作者: G莫_小语 | 来源:发表于2018-03-08 18:57 被阅读0次

类与实例

类的声明
  • ES5
  // 类的声明
  function Animal() {
    this.name = 'jack'
  }
// 实例化
let a = new Animal()
  • ES6
  // 类的声明
  class Animal2 {
    constructor() {
      this.name = 'jack'
    }
  }
  // 实例化
  let a = new Animal2()

生成实例

类与继承

如何实现继承
继承的几种方式
  • 原型链是实现继承的主要方法
  1. 借助构造函数
function Parent1() {
  this.name = 'parent1'
}
Parent1.prototype.say = function () { } // Child1的实例没法继承原型链上的属性方法

function Child1() {
  Parent1.call(this)  // 改变 this 上下文,Parent1构造函数的this指向Child1构造函数的实例
  this.type = 'child1'
}
let person = new Child1  // {name: "parent1", type: "child1"}
person.say()  // 报错
  • 注意:如果父类有参数,可以在call中传递参数,call中的第二个参数开始就是函数中的参数。
  • 原理:用call来改变this的指向,使Parent1构造函数的this指向Child1构造函数的实例
  • 缺点:只实现部分继承,只能继承Parent1函数中的属性和方法,Parent1原型链上的东西Child1没法继承。

  1. 借助原型链实现继承
function Parent() {
  this.name = 'parent'
  this.play = [1, 2, 3]
}
Parent.prototype.say = function () { }
function Child() {
  this.type = 'child'
}
Child.prototype = new Parent()  // 重点
let s1 = new Child()
let s2 = new Child()
s1.play.push(4) // s2 也变成了 [1, 2, 3, 4]
// 缺点:本来只想改变 s1 ,但 s2 也跟着改变了,两个实例对象应该隔离无关
  • 原理:当访问实例的属性方法时,本身没有的话会沿着实例的__proto__往上寻找,因为构造函数的prototype跟实例的__proto__指的同一块空间,所以改变prototype的话,实例的__proto__也会跟着改变,从而实现继承
  • 缺点:如果原型链上有引用类型的值,那么某一实例改变了值其他实例也会跟着改变,因为指的同一个地址,实例的constaructor属性指向Parent,子类的constructor属性是从父类原型上继承来的,所以指向Parent

  1. 组合继承方式
function Parent() {
  this.name = 'parent'
  this.play = [1, 2, 3]
}
Parent.prototype.say = function () { }
function Child() {
  Parent.call(this)
  this.type = 'child'
}
Child.prototype = new Parent()
let s1 = new Child()
let s2 = new Child()
s1.play.push(4)  // 没有改原型链上的,改的是自己的,call执行时赋值,原型链上也有play
  • 原理:把上面两种合为一种实现,这种方式是真正写面向对象继承最通用的方式。
  • 缺点:父类的构造函数执行了两次,在call的时候执行了一次,在原型的时候new Parent的时候又执行了一次,并且后一次执行导致原型上出现了重复属性方法,实例的constructor属性指向Parent

  1. 组合继承优化一
function Parent() {
  this.name = 'parent'
  this.play = [1, 2, 3]
}
Parent.prototype.say = function () { }
function Child() {
  Parent.call(this)  // 已经拿到父类里的方法属性了,后面不需要再new,只需要把父类原型上的东西也继承过来
  this.type = 'child'
}
Child.prototype = Parent.prototype  // 把父类原型上的东西也继承过来
Child.prototype.age = 33  // 父类的原型也添加了age属性,子类改变父类不应该改变
let s1 = new Child()
let s2 = new Child()
s1.play.push(4)
console.log(s1.constructor)  // Parent
console.log(s2.constructor)  // Parent
// 因为Child实现继承的时候把Parent原型里的constructor属性也继承过来了,
// 而Parent原型里的constructor属性指向的肯定是Parent,所以出现了混乱
// 实际应该指向Child
// 实例的构造函数都指向了Parent,无法确定实例的构造函数
  • 缺点:
  1. 如果给子类原型添加属性方法的话父类的原型也会跟着添加,不符合逻辑,子类不应该影响父类
    2.实例的constructor属性应该指向child构造函数,这样才符合预期要求

  1. 组合继承优化二
function Parent() {
  this.name = 'parent'
  this.play = [1, 2, 3]
}
Parent.prototype.say = function () { }
function Child() {
  Parent.call(this)
  this.type = 'child'
}
Child.prototype = Object.create(Parent.prototype)  // 现在子类改变了父类不会改变
Child.prototype.constructor = Child  // 手动设置一个构造函数,这里如果第三项照这样改的话改的是父类的constructor,而不是子类的constructor
Child.prototype.age = 33  // 父类的原型也没有添加
let s1 = new Child()
let s2 = new Child()
s1.play.push(4)
console.log(s1.constructor)  // Child
console.log(s2.constructor)  // Child

相关文章

  • PHP全栈学习笔记8

    面向对象的基本概念,面向对象编程,oop,面向对象,面向对象的分析,面向对象的设计,面向对象的编程,什么是类。 类...

  • PHP全栈学习笔记8

    面向对象的基本概念,面向对象编程,oop,面向对象,面向对象的分析,面向对象的设计,面向对象的编程,什么是类。 类...

  • Python 面向对象 - 01 基本概念

    目录一、面向过程 和 面向对象 基本概念1.1 面向过程1.2 面向对象二、类和对象2.1 类2.2 对象2.3 ...

  • 3. Java面向对象编程

    类与对象[1] Java是面向对象的汇编语言(面向机器)—— c语言(面向过程)—— java语言(面向对象) 类...

  • 007-类和对象

    Java - 强制面向对象 类 Python - 既支持面向对象,也支持面向过程 1、类、对象 类是对某一类具有共...

  • 《Java核心技术卷 I》之 Java对象与类

    Java对象与类 面向对象程序设计 面向对象程序设计,简称OOP,Java语言就是完全面向对象的。 类 类(cla...

  • Jade - Java 面向对象1

    面向对象关键 面向对象 相对于 面向过程(一步一步) 类: 类是对象的模板 对象: 对象是类的一个实例 类: 一组...

  • java基础-day07-面向对象

    面向对象 1. 面向对象 1.1 生活中的面向对象和面向过程 1.2 类和对象 类对象人类马云爸爸,麻花藤,乔布斯...

  • 面向对象.类.对象

    面向对象 类、对象

  • Python面向对象(基础)

    面向对象 Python是支持面向对象的,面向对象编程是一种程序设计思想。 类和实例(基础) 面向对象最重要的就是类...

网友评论

      本文标题:面向对象类

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