• class(一)--类的创建


    class是ES6引入的,它并不是一种全新的继承模式,而只是基于原型对象继承封装的语法糖,因此只要充分理解原型对象,原型链,继承等知识,class也就很好容易理解了

    类的声明

    ES5及之前是通过创建一个构造函数(Fn)以及将方法指派到该构造函数的原型对象(Fn.prototype)上,来创建一个类。

    在ES6中类的声明就十分简单了,只要以class关键字开始, 接上类名, 最后将方法编写在花括号{}里面。(注意点:方法之间不需要逗号,方法之间不需要逗号,方法之间不需要逗号

    class Person {
      // 等价于 Person构造函数
      constructor(name) {
        this.name = name;
      }
      // 等于Person.prototype.sayHello
      sayHello() {
        console.log(`Hello, my name is ${this.name}`);
      }
    }
    
    let me = new Person('mxk');
    console.log(me.name); // mxk
    console.log(me.sayHello()) // Hello, my name is mxk
    
    console.log(me instanceof Person) // true
    console.log(typeof Person) //function
    console.log(Object.getPrototypeOf(me) === Person.prototype) // true
    console.log(Person.prototype.constructor === Person) // true
    

    类表达式

    匿名函数表达式

    let Person = class {
      constructor(name) { this.name = name; }
    }
    

    具名函数表达式

    let Person = class Person1{
      constructor(name) { this.name = name; }
    }
    

    与函数的声明和表达式不同,函数声明是会被提升的,但是类的声明和表达式都不存在提升,因此它们主要的不同就是代码风格

    类的特点

    1. 类声明不会被提升,这与函数定义不同。类声明的行为与 let 相似,因此在程序的执行到达声明处之前,类会存在于暂时性死区内。
    2. 类声明中的所有代码会自动运行在严格模式下,并且也无法退出严格模式。
    3. 类的所有方法都是不可枚举的,而自定义类创建的方法默认是可枚举的
    4. 类的所有方法内部都没有 [[Construct]] ,因此使用 new 来调用它们会抛出错误。
    5. 调用类构造器时不使用 new ,会抛出错误。
    6. 不得修改类内部的类名

    模拟类的创建

    let/*不会被提升*/ Person /*外部可以访问的*/  = (function() {
      "use strict"; /*运行在严格模式下*/
    
      const /*不能修改内部的类名*/ Person1 = function(name) {
        if (new.target === void 0) {
          throw new Error('构造函数必须使用new');
        }
        this.name = name;
      }
    
      Object.defineProperty(Person1.prototype, 'sayHello', {
        value: function() {
          if (new.target !== void 0) {
            throw new Error('类内方法调用不能使用new')
          }
          console.log(`Hello, my name is ${this.name}`);
        },
        enumerable: false, /*类内所有的方法都是不可枚举的*/
        writable: true,
        configurable: true
      })
    
      return Person1;
    })();
    

    类的声明和表达式基本是一致的,函数声明暴露给外部的类名和内部的类名是相同的,类表达式的话只有赋值符号左边的类名是我们可以访问的,右侧那个是内部的类名

    立即调用类构造函数

    let me = new class {
      constructor(name) { this.name = name; }
    
      sayHello() {
        console.log(`Hello, my name is ${this.name}`);
      }
    }('mxk');
    
    console.log(me.name) // mxk
    console.log(me.sayHello()) // Hello, my name is mxk
    

    使用这种模式你无法访问到类,因为外部可以访问的类名它并没有暴露出来

    访问器属性

    class Person {
      constructor(name, age) {
        this.name = name;
        this.__age = age
      }
    
      get age() {
        return this.__age;
      }
    
      set age(value) {
        this.__age = value + 1;
      }
    }
    相当于
    Object.defineProperty(Person.prototype, 'age', {
      enumerable: false, /*不可枚举*/
      configurable: true,
      get() { return this.__age; },
      set(value) { this.__age = value + 1; }
    })
    

    静态成员

    直接定义在构造函数对象上的方法,实例对象无法访问到

    class ClassType {
      constructor() {
        this.type = 'class_type';
      }
    
      static create() {
        return new ClassType();
      }
    }
    
    let ct = ClassType.create();
    console.log(ct.type); //class_type
    console.log(ct.create); // undefined
    
  • 相关阅读:
    RFC7296--Internet密钥交换协议版本2(IKEv2)
    IPSec 100问
    strongswan--函数定义宏
    RFC6311--协议支持IKEv2 / IPsec的高可用性
    IPSec之security acl
    华罗庚
    韩罗塔核心算法
    javaBean
    Servlet
    javaee Api
  • 原文地址:https://www.cnblogs.com/guanine/p/9273098.html
Copyright © 2020-2023  润新知