OOP面向对象编程,程序中的所有操作都是由他的对象完成的。 封装--安全性,继承--扩展性,多态--灵活性。
一、原型
原型是javaScript实现面向对象的方式。对象中存储属性的区域有两个:
- 1.对象自身,直接通过对象所添加的属性,在类中通过x=y形式所添加的属性(包括箭头函数、set = function(){}形式)。
- 2.原型对象(prototype)会帮助对象存储一些属性,在对象中会有一个属性用来存储原型对象,叫__proto__,当访问对象的属性时,优先访问对象本身,当没有时,则去访问对象的原型,会添加到原型对象的情况:1.在类中通过使用xxx(){}声明的方法。2.主动向原型里添加
原型对象中的数据:对象中的数据(属性和方法),consructor(对象的构造函数), 原型对象也有原型,这样就构成了一条原型链,根据对象的复杂程度不同,原型链的长度也不同,例如:实例对象-->原型-->原型(object对象的原型)-->null。
所有的同类对象他们的原型对象都是同一个。
原型的作用:相当于的一个公共空间,可以被所有的实例访问。可以将一个该类实例中所有的公共属性统一存放到原型中,这样只需创建一个属性,就可以被所有实例访问。js中继承就是通过原型实现的:当继承时,子类的原型就是父类的实例。
class animal{
}
class cat extends animal{
}
class tomCat extends cat{
}
//tomCat-->cat-->animal实例-->object-->Object原型-->null
函数的__proto__是f(),f()的__proto__是Object原型.
修改原型
- 尽量不要手动修改原型
- 不要通过类的实例去修改,会影响所有同类对象
- 可以通过类的prototype属性来访问实例的原型
/*
可以使用instanceof检查一个对象是否由一个类创建的,
instanceof检查的是对象的原型链上是否有该类实例,只要有就返回true
dog -> animail实例 ->object实例 ->Object原型
*/
class animali{ }
class Dog extends animail{}
cosnt dog = new Dog() //相当于const dog = {} 就是一个对象object
/*
检查一个对象自身是否具有一个属性方法
*/
//1.in 使用in时,会检查对象自身和原型
console.log("name" in p )
//2.对象.hasOwnProperty(属性名) 不推荐
console.log(p.hasOwnProperty("sayhello"))
//3.Object.hasOwn(对象,属性名)
console.log(Object.hasOwn(p,"name"))
二、封装
封装主要用来保证数据的安全,实现方式:1.属性私有化,加# 2.通过getter和setter操作属性。
/*类是创建对象的模板。由同一个类(Class)所创建的对象叫同类对象
封装 多态
*/
Class Person{
#name //加上#表示私有变量
#age
#gender
static test = "he" //使用static声明的属性是静态属性,只能通过类去访问,实例访问不到
say(){
console.log(this) //this指向调用的实例
}
static sayhello(){ //使用static声明的方法是静态方法,只能通过类去调用,实例访问不到
console.log(this) //this指向person类
}
constructor(a,b,c){ //在使用new关键字调用类创建对象实例时执行
this.#name = a //调用构造方法给属性赋值,类中属性可不写
this.#age = b
this.#gender = c
}
//getter方法,用来读取属性
getName(){
return this.#name
}
get gender(){
return this.#name
}
//setter方法,用来设置属性
setName(name){
this.#name = name
}
}
const p1 = new Person("孙悟空",16,"男") //创建实例
p1.say()
Person.sayhello()
p1.gender() //使用此方式可以调用get gender()方法
三、继承
/*继承
*/
class animal{
consructor(name){
this.name = name
}
say(){
console.log("动物在叫")
}
}
class Dog extends animal{
//重写构造函数
consructor(name){
super() //重写构造函数时,第一行必须是super()
//可以通过super(name)方式给父类传参,或者直接在子类中赋值this.name = name
}
//重写父类方法
say(){
super.say() //可以使用super调用父类方法
console.log("汪汪")
}
}