JavaScript面向对象编程笔记

166次阅读
没有评论

共计 2497 个字符,预计需要花费 7 分钟才能阅读完成。

构造函数和原型

ES6 之前没有提供 extends 继承,可以通过构造函数 + 原型对象模拟实现继承,被称为组合继承。

call()

调用这个函数并且修改函数运行时的 this 指向。

function fn() {console.log(this)
}
const obj = {name: "佩奇",}
fn() //Window
fn.call(obj) //Object

继承父类属性:

function Father(name, age) {
  this.name = name
  this.age = age
}
function Son(name, age, score) {
  // 把父构造函数的 this 改为子构造函数的 this
  Father.call(this, name, age, score)
  this.score = score
}
const son = new Son("佩奇", 10, 99)
console.log(son) //Son {name: '佩奇', age: 10, score: 99}

继承父类方法:

function Father(name, age) {
  this.name = name
  this.age = age
}
Father.prototype.money = function () {console.log(10000)
}
function Son(name, age, score) {
  // 把父构造函数的 this 改为子构造函数的 this
  Father.call(this, name, age, score)
  this.score = score
}
Son.prototype = new Father()
Son.prototype.constructor = Son // 利用 constructor 指回用来的构造函数
Son.prototype.exam = function () {console.log("儿子要考试!")
}
const son = new Son("佩奇", 10, 99)
console.log(Son.prototype.constructor) //Son

类是对象模板,可以将对象中的属性和方法直接定义在类中。定义后,就可以直接通过类来创建对象。通过同一个类创建的对象,称为同类对象。可以使用 instanceof 来检查一个对象是否是由某个类创建,如果是则称该对象是这个类的实例。

class Person {}
const p = new Person() // 调用构造函数,创建实例对象
console.log(p instanceof Person) // true

类中的所有代码都会在严格模式下执行。严格模式下其中一个特点就是,函数的 this 不在是 window,而是 undefined。

注意:

  • 在类中方法的 this 不是固定的:以方法形式调用时,this 就是当前的实例;以函数形式调用,this 是 undefined
  • 在有些场景下,希望方法中的 this 是固定的,不会因调用方式不同而改变。可以使用箭头函数来定义类中的方法,则方法中的 this 恒为当前实例,不会改变。

属性与方法

class Person {
  name = 'Tom' // 实例属性
  age = 25
  // 实例方法
  sayHi() {console.log(`Hi, my name is ${this.name}`)
  }

  static sex = 'male' // 静态属性(类属性)// 静态方法(类方法)static sayHi() {console.log('Hi, I am a person')
  }
}

const p = new Person()
console.log(p.name) // Tom
p.sayHi() // Hi, my name is Tom

console.log(Person.sex) // male
Person.sayHi() // Hi, I am a person

构造函数

class Person {
  // 构造函数在调用类创建对象时执行
  constructor(name, age) {
    this.name = name
    this.age = age
  }
}

const p = new Person('Tom', 25)
console.log(p.name, p.age) // Tom 25

封装

封装主要用来保证数据的安全,实现封装的方式:

  • 属性私有化:加 #
  • 通过 getter 和 setter 方法来操作属性

对象是一个用来存储不同属性的容器,不仅存储属性,还要负责数据的安全。直接添加到对象中的属性,并不安全,因为它们可以被任意的修改。

如何确保数据的安全:

  • 私有化数据:将需要保护的数据设为私有,只能在类内部使用
  • 提供 setter 和 getter 方法来开放对数据的操作,好处是可以控制属性的读写权限,可以在方法中对属性值进行验证
class Person {
  #age // 加上 #表示私有属性,只能在类的内部访问
  constructor(name, age) {
    this.name = name
    this.#age = age
  }

  get age() {return this.#age}

  set age(value) {if (value < 0) {throw new Error('Age cannot be negative')
    }
    this.#age = value
  }
}

const p = new Person('Tom', 25)
console.log(p) // Person {name: 'Tom', #age: 25}
p.age = 100
console.log(p) // Person {name: 'Tom', #age: 100}

多态

在 JS 中不会检查参数类型,这就意味着任何数据都可以作为参数传递。要调用某个函数,无需指定类型,只要对象满足某些条件即可。如果一个东西走路像鸭子,叫起来像鸭子,那么它就是鸭子。多态为我们提供了灵活性。

class Dog {constructor(name) {this.name = name}
}

class Cat {constructor(name) {this.name = name}
}

const dog = new Dog('旺财')
const cat = new Cat('小白')

function sayHello(animal) {console.log(` 你好,${animal.name}`)
}

sayHello(dog) // 你好,旺财
sayHello(cat) // 你好,小白 

正文完
 0
三毛笔记
版权声明:本站原创文章,由 三毛笔记 于2023-08-02发表,共计2497字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)
验证码