zoukankan      html  css  js  c++  java
  • ja类主体和方法定义

    类主体和方法定义

    类的主体是放在大括号中的部分{}在这里定义类成员,例如方法或构造函数。

    严格模式

    类的主体以严格模式执行,即,此处编写的代码将采用更严格的语法以提高性能,否则将抛出一些其他的静默错误,并且某些关键字保留给将来的ECMAScript版本。

    建设者

    constructor方法是用于创建和初始化使用创建的对象的特殊方法class在一个类中,只能有一个名为“ constructor”的特殊方法。SyntaxError如果该类包含一个以上的constructor方法实例,则将引发A。

    构造函数可以使用super关键字来调用超类的构造函数。

    原型方法

    另请参见方法定义

    class Rectangle {
      constructor(height, width) {
        this.height = height;
        this.width = width;
      }
      // Getter
      get area() {
        return this.calcArea();
      }
      // Method
      calcArea() {
        return this.height * this.width;
      }
    }
    
    const square = new Rectangle(10, 10);
    
    console.log(square.area); // 100

    静态方法

    static关键字定义为一类的静态方法。静态方法被称为没有实例化的类并不能通过类实例调用。静态方法通常用于为应用程序创建实用程序功能。

    class Point {
      constructor(x, y) {
        this.x = x;
        this.y = y;
      }
    
      static distance(a, b) {
        const dx = a.x - b.x;
        const dy = a.y - b.y;
    
        return Math.hypot(dx, dy);
      }
    }
    
    const p1 = new Point(5, 5);
    const p2 = new Point(10, 10);
    p1.distance; //undefined
    p2.distance; //undefined
    
    console.log(Point.distance(p1, p2)); // 7.0710678118654755
    

    this与原型和静态方法绑定

    当调用静态或原型方法而没有for的值时  this,例如通过将变量分配给该方法然后调用它,则该this值将undefined在方法内部。即使"use strict"指令不存在,此行为也将是相同的,因为class主体的语法边界内的代码始终以严格模式执行。

    class Animal { 
      speak() {
        return this;
      }
      static eat() {
        return this;
      }
    }
    
    let obj = new Animal();
    obj.speak(); // the Animal object
    let speak = obj.speak;
    speak(); // undefined
    
    Animal.eat() // class Animal
    let eat = Animal.eat;
    eat(); // undefined

    如果我们在非严格模式下使用传统的基于函数的语法重写以上内容,则this方法调用将自动绑定到初始this值,默认情况下,该初始值为全局对象在严格模式下,将不会发生自动绑定。this保持不变的价值

    function Animal() { }
    
    Animal.prototype.speak = function() {
      return this;
    }
    
    Animal.eat = function() {
      return this;
    }
    
    let obj = new Animal();
    let speak = obj.speak;
    speak(); // global object (in non–strict mode)
    
    let eat = Animal.eat;
    eat(); // global object (in non-strict mode)
    

    实例属性

    实例属性必须在类方法内定义:

    class Rectangle {
      constructor(height, width) {    
        this.height = height;
        this.width = width;
      }
    }

    静态(类方面)数据属性和原型数据属性必须在ClassBody声明之外定义:

    Rectangle.staticWidth = 20;
    Rectangle.prototype.prototypeWidth = 25;
    

    现场申报

    公共和私有字段声明是JavaScript标准委员会TC39提出实验性功能(第3阶段)对浏览器的支持是有限的,但是可以通过构建步骤(如Babel)使用该功能

    公共领域声明

    使用JavaScript字段声明语法,上面的示例可以写成:

    class Rectangle {
      height = 0;
      width;
      constructor(height, width) {    
        this.height = height;
        this.width = width;
      }
    }
    

    通过预先声明字段,类定义变得更加自我记录,并且字段始终存在。

    如上所示,可以使用默认值或不使用默认值来声明字段。

    有关更多信息,请参见公共类字段

    私人领域声明

    使用私有字段,可以按以下方式细化定义。

    class Rectangle {
      #height = 0;
      #width;
      constructor(height, width) {    
        this.#height = height;
        this.#width = width;
      }
    }
    

    从类外部引用私有字段是错误的。它们只能在类主体中读取或写入。通过定义在类外部不可见的内容,可以确保类的用户不会依赖于内部,这可能会导致版本之间的差异。

    私有字段只能在字段声明中预先声明。

    以后无法通过分配普通属性的方式来分配专用字段来创建专用字段。

    有关更多信息,请参见私有类字段

    子分类 extends

    extends关键字用于类声明类表达式中,以将一个类创建为另一个类的子级。

    class Animal { 
      constructor(name) {
        this.name = name;
      }
      
      speak() {
        console.log(`${this.name} makes a noise.`);
      }
    }
    
    class Dog extends Animal {
      constructor(name) {
        super(name); // call the super class constructor and pass in the name parameter
      }
    
      speak() {
        console.log(`${this.name} barks.`);
      }
    }
    
    let d = new Dog('Mitzie');
    d.speak(); // Mitzie barks.
    

    如果子类中存在构造函数,则需要先调用super(),然后再使用“ this”。

    也可以扩展传统的基于功能的“类”:

    function Animal (name) {
      this.name = name;  
    }
    
    Animal.prototype.speak = function () {
      console.log(`${this.name} makes a noise.`);
    }
    
    class Dog extends Animal {
      speak() {
        console.log(`${this.name} barks.`);
      }
    }
    
    let d = new Dog('Mitzie');
    d.speak(); // Mitzie barks.
    
    // For similar methods, the child's method takes precedence over parent's method

    请注意,类不能扩展常规(不可构造)对象。如果要从常规对象继承,则可以使用Object.setPrototypeOf()

    const Animal = {
      speak() {
        console.log(`${this.name} makes a noise.`);
      }
    };
    
    class Dog {
      constructor(name) {
        this.name = name;
      }
    }
    
    // If you do not do this you will get a TypeError when you invoke speak
    Object.setPrototypeOf(Dog.prototype, Animal);
    
    let d = new Dog('Mitzie');
    d.speak(); // Mitzie makes a noise.
    

    种类

    您可能要返回Array派生数组类中的对象MyArray种类模式可让您覆盖默认构造函数。

    例如,当使用诸如这样的方法map()返回默认构造函数时,您希望这些方法返回父Array对象而不是MyArray对象。Symbol.species符号使您可以执行此操作:

    class MyArray extends Array {
      // Overwrite species to the parent Array constructor
      static get [Symbol.species]() { return Array; }
    }
    
    let a = new MyArray(1,2,3);
    let mapped = a.map(x => x * x);
    
    console.log(mapped instanceof MyArray); // false
    console.log(mapped instanceof Array);   // true
    

    超级班级通话 super

    super关键字用来调用父类的相应方法。与基于原型的继承相比,这是一个优势。

    class Cat {
      constructor(name) {
        this.name = name;
      }
      
      speak() {
        console.log(`${this.name} makes a noise.`);
      }
    }
    
    class Lion extends Cat {
      speak() {
        super.speak();
        console.log(`${this.name} roars.`);
      }
    }
    
    let l = new Lion('Fuzzy');
    l.speak(); 
    // Fuzzy makes a noise.
    // Fuzzy roars.
    

    混入

    抽象子类或混入是类的模板。ECMAScript类只能有一个超类,因此,例如,无法从工具类进行多重继承。该功能必须由超类提供。

    具有超类作为输入和扩展该超类作为输出的子类的函数可用于在ECMAScript中实现混入:

    let calculatorMixin = Base => class extends Base {
      calc() { }
    };
    
    let randomizerMixin = Base => class extends Base {
      randomize() { }
    };
    

    然后,可以使用以下方式编写使用这些混入的类:

    class Foo { }
    class Bar extends calculatorMixin(randomizerMixin(Foo)) { }

     

  • 相关阅读:
    Unity3D启动报错的解决方案
    Unity3D引用dll打包发布的问题及解决
    轻量级C#网络通信组件StriveEngine —— C/S通信开源demo(附源码)
    k8s 各种网络方案
    网络模型
    管理和安装 chart
    开发自己的 chart
    再次实践 MySQL chart
    chart 模板
    chart 目录结构
  • 原文地址:https://www.cnblogs.com/jameswohu/p/13602614.html
Copyright © 2011-2022 走看看