你不知道的Class细节

270 阅读3分钟

这是我参与8月更文挑战的第4天,活动详情查看:  8月更文挑战

class类,通常标识一个相同类型的共有属性,

"Class"语法

class people {
  // class 方法
  constructor() { ... }
  computergame() { ... }
  basketball() { ... }
  eat() { ... }
}

然后我们通过 new people()可以创建一个具有以上方法的对象。 new 会自动调用 constructor()中的方法,所以我们可以在constructor()中初始化对象 例如:

lass User {
​
  constructor(name) {
    this.name = name;
  }
​
  sayHi() {
    alert(`my name is ${this.name}`);
  }
​
}
​
// 用法:
let user = new User("coolFish");
user.sayHi();

new User("John") 被调用:

  1. 一个新对象被创建。
  2. constructor 使用给定的参数运行,并为其分配 this.name

……然后我们就可以调用对象方法了,例如 user.sayHi类的方法之间没有逗号

什么是Class

本质是一个函数

class User {
  constructor(name) { this.name = name; }
  sayHi() { alert(this.name); }
}
​
// 佐证:User 是一个函数
alert(typeof User); // function

那我们会产生疑问,为什么类的本质是一个函数。

实例.__proto__ === 原型
实例.contructor === 构造函数
构造函数.prototype === 原型
实例.contructor === 构造函数
//类,更确切地说,是 constructor 方法
alert(User === User.prototype.constructor); // true
// 方法在 User.prototype 中,例如:
alert(User.prototype.sayHi); // alert(this.name);

小结:我们可以知道,实例的原型 prototype 的 constructor 就是实例的构造函数。 我们来看一个 class User和一个纯函数构建的 User class 声明

class User {
  constructor(name) { this.name = name; }
  sayHi() { alert(this.name); }
}

用纯函数重写 class User

// 1. 创建构造器函数
function User(name) {
  this.name = name;
}
// 函数的原型(prototype)默认具有 "constructor" 属性,
// 所以,我们不需要创建它
// 2. 将方法添加到原型
User.prototype.sayHi = function() {
  alert(this.name);
};
// 用法:
let user = new User("John");
user.sayHi();

小结:我们看到两种方法的出的结果基本相同,但是他们之间依旧存在重大的差异。 差异:

  1. 通过class 创建的函数具有特殊的内部属性标记[[FunctionKind]]:"classConstructor"
  2. 与普通函数不同,必须使用new来调用
  3. 类方法不可枚举。 类定义将 "prototype" 中的所有方法的 enumerable 标志设置为 false
  4. 类总是使用 use strict。 在类构造中的所有代码都将自动进入严格模式

Class的getter和setter

与 ES5 一样,在“类”的内部可以使用get和set关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为。

 class demo{
            constructor(age){
                this.age = agie;
                this._age = age;
            }
            get age(){
                return this._age;
            }
            set age(value){
                this._age = value;
                console.log("年龄"+value);
            }
        }
        let coolFish = new demo(9);
        coolFish.age = 18;
        console.log(coolFish.age);

Class的私有方法和私有属性

私有方法和私有属性:是只能在类的内部访问的方法和属性,外部不能访问。 这是常见需求,有利于代码的封装,但 ES6 不提供,只能通过变通方法模拟实现。

_bar方法前面的下划线,表示这是一个只限于内部使用的私有方法。但是,这种命名是不保险的,在类的外部,还是可以调用到这个方法

class Cat{
            #eyes = "眼睛";
            static pai(){
                console.log("凯文");
            }
            say(){
                Cat.pai();
                console.log("猫有一双大大的"+this.#eyes);
            }
        }
        let kate=new Cat();
        kate.say();

私有属性也可以设置 getter 和 setter 方法。

私有属性不限于从this引用,只要是在类的内部,实例也可以引用私有属性。