【JS】面向对象-封装-私有和受保护的属性和方法
在面向对象的编程中,属性和方法分为两组:
内部接口 —— 可以通过该类的其他方法访问,但不能从外部访问的方法和属性。
外部接口 —— 也可以从类的外部访问的方法和属性。
在 JavaScript 中,有两种类型的对象字段(属性和方法):
公共的:可从任何地方访问。它们构成了外部接口。
私有的:只能从类的内部访问。这些用于内部接口。
“受保护”的字段:只能从类的内部和基于其扩展的类的内部访问(例如私有的,但可以从继承的类进行访问),受保护的字段不是在语言级别的 Javascript 中实现的。
1. 受保护字段的实现
// class Animal {
// animalNumber = 100
// }
// let animal = new Animal()
// console.log(animal.animalNumber); // 100
// 此时属性animalNumber是公共的
// 使用setter和getter将其设置为受保护的
// 受保护的属性通常以下划线 _ 作为前缀
class Animal {
_animalNumber = 100
set animalNumber(value){
if(value < 0){
value = 0
}
this._animalNumber = value
}
/*
也可写为:
setAnimalNumber(value){
if(value < 0){
value = 0
}
this._animalNumber = value
}
这样可以接受多个参数
}
*/
get animalNumber(){
return this._animalNumber
}
}
let animal = new Animal()
animal.animalNumber = -12
console.log(animal.animalNumber); // 0
// 此时animalNumber只能被设置为大于等于0的数
// 若想让一个属性变为只读的,可以只设置getter不设置setter
// 受保护的字段是可以被继承的
class Dog extends Animal{
test(){
console.log(this._animalNumber); // 可以访问到父类受保护的__animalNumber属性
}
}
let d = new Dog()
d.test()
2. 私有属性
1.私有属性和方法应该以 # 开头,它们只在类的内部可被访问。
class Animal {
#size = 900
}
let a = new Animal()
// console.log(a.#size); //Private field '#size' must be declared in an enclosing class 私有字段“#size”必须在封闭类中声明
2. 私有字段与公共字段不会发生冲突。我们可以同时拥有私有的和公共的同名字段。
3. 私有字段由语言本身强制执行,无法从外部或从继承的类中访问它,可以使用getter和setter进行访问。
class Animal {
#size = 900
get size(){
return this.#size
}
set size(value){
this.#size = value
}
}
let a = new Animal()
console.log(a.size); // 900
a.size = 800
console.log(a.size); // 800
4. 私有字段不能通过 this[name] 访问
class Animal {
#size = 900
get size(){
return this['#size']
}
set size(value){
this.#size = value
}
}
let a = new Animal()
console.log(a.size); // undefined
a.size = 800
console.log(a.size); // undefined
受保护的属性和方法:只能从类和扩展类的内部访问,通常以_开头(自定义)。
私有的属性和方法:只能在类自己内部访问,以#开头,可以通过getter和setter在外部进行访问。