共计 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) // 你好,小白
正文完