【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在外部进行访问。

posted @ 2022-10-29 12:04  Ahoge的笔记本  阅读(257)  评论(0编辑  收藏  举报