首页 > 其他分享 >UES-09-类

UES-09-类

时间:2024-05-31 16:26:29浏览次数:16  
标签:name 09 constructor let 基类 new class UES

仿类结构

先创建一个构造器函数,然后在这个函数的原型中存储方法,这个构造器函数生成的实例从原型继承了存储的方法。

function Con(n) {
  this.n = n;
}

Con.prototype.fun = function () {
  console.log(this.n);
};

let c = new Con("zzz");
c.fun(); // "zzz"

类的声明

class Name {
  constructor(name) {
    this.name = name;
  }

  say() {
    console.log(this.name);
  }
}

let n = new Name("xqy");
n.say();    // "xqy"
typeof Name // "function"

声明的类本质上还是一个函数,类的方法依然作为属性存储在这个函数的原型中。

自有属性(own properties)是定义在实例而不是原型上的属性,一般在类的构造器中进行声明。

类声明不会发生自举,和 let 定义变量类似。
类声明默认在严格模式下执行,不会退出严格模式。
类中定义的方法(不包括构造器)不可枚举。
类中的方法如果没有 [[Construct]] 属性,则不能使用 new 调用,使用 new 调用会抛出错误。
类中的构造器只能使用 new 调用,不使用 new 调用会抛出错误。
类名在类的内部视为 const 变量,不可更改,否则抛出错误。但是类名在类的外部视为 let 定义的变量,可以更改。

类表达式

与上面类声明等价的类表达式为

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

  say() {
    console.log(this.name);
  }
}

创建有名称的类表达式

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

  say() {
    console.log(this.name);
  }
}

typeof Name  // "function"
typeof Inner // undefined

Inner 是具名类表达式的名称,这个名称相当于是在类的内部定义,在类的外部无法访问,所以返回结果为 undefined。

类可以当作值来使用,也可以作为函数参数、函数返回值,给变量赋值。

立即调用类构造器创建单例

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

  say() {
    console.log(this.name);
  }
}("xyz");

n.say(); // "xyz"

在创建类的时候传递参数实例化该类,该类的自有属性已经被固定,同时该类也只有一个实例和一个引用。

访问器属性

访问器属性实质上是在原型中定义的。下面的代码片段中 getValue()setValue(v) 方法都是定义在 Num 的原型中。value 是自有属性,定义在实例上。

class Num {
  constructor(v) {
    this.value = v;
  }
  
  get value() {
    return this.value;
  }
  
  set value(v) {
    this.value = v;
  }
}

计算的成员名

类中的方法名和访问器属性可以使用需计算的名称。

let mName = "say",
    n = "num";
class Num {
  constructor(name, v) {
    this.name = name;
    this.value = v;
  }
  
  [mName]() {
    console.log(this.name);
  }
  
  get [n]() {
    return this.value;
  }
  
  set [n](v) {
    this.value = v;
  }
}

let n = Num("xyz", 25);
n.say(); // "xyz"

生成器方法

在类中可以创建生成器。为 Symbol.iterator 属性定义一个生成器作为默认的迭代器。

class Coll {
  constructor() {
    this.items = [];
  }
  
  *[Symbol.iterator]() {
    yield *this.items.values();
  }
}

静态成员

类本身具有的方法或属性称为静态成员,静态成员不属于类的原型。访问静态成员不能使用类实例而需要直接使用类。类成员前面添加 static 表示该成员是静态的,构造器不允许是静态成员。

class Name {
  constructor(name) {
    this.name = name;
  }
  
  // 等价于 Name.prototype.say()
  say() {
    console.log(this.name);
  }
  
  // 等价于 Name.create()
  static create(name) {
    return new Name(name);
  }
}

let n = Name.create("xyz");

派生类继承

类的继承使用 extends

class Rect {
  constructor(length, width) {
    this.length = length;
    this.width = width;
  }
  
  getArea() {
    return this.length * this.width;
  }
}

class Square extends Rect {
  constructor(length) {
    super(length, length);
  }
}

let s = new Square(3);
s.getArea(); // 9

子类中如果自定义构造器,则必须在构造器中调用 super() 初始化基类,super 表示基类。如果不定义构造器,则默认构造器会在用 new 创建子类时,将传入子类的所有参数作为 super 的参数调用 super()

只能在子类中使用 super()。在构造器中必须在 super() 语句调用之后才能访问 this,因为 this 需要 super() 调用之后才会初始化。构造器中不使用 super() 的唯一方式是构造器返回一个对象。

子类中定义与基类同名的方法时,子类中的方法会屏蔽基类中的同名方法。如果此时需要调用基类中被屏蔽的方法,使用 super.method() 访问。

类继承中,基类中的静态成员会被子类继承。

具有 [[Construct]] 属性和原型的函数可以作为基类使用 extends 被继承。任何结果(返回值)为前述函数的表达式(函数)可以位于 extends 后面使用。

继承内置对象时,this 的值先由基类创建,再被子类修改。子类的行为默认与基类(内置对象)一致。返回内置对象实例的方法如果接收的参数为继承自内置对象的子类,则该方法返回的实例类型为这个子类。

Symbol.species 是返回一个函数的静态访问器属性。类的方法(构造器除外)需要创建一个新实例时,会调用 Symbol.species 返回的函数作为构造器创建这个类实例。

内置类型 Array、ArrayBuffer、Map、Promise、RegExp、Set、类型化数组的默认 Symbol.species 返回的是 this。

class Base {
  constructor(v) {
    this.value = v;
  }
  
  // this.constructor[Symbol.species] 为 Symbol.species 返回的函数
  duplicate() {
    return new this.constructor[Symbol.species](this.value);
  }
  
  static get [Symbol.species]() {
    return this;
  }
}

class Sub1 extends Base {}
class Sub2 extends Base {
  static get [Symbol.species]() {
    return Base;
  }
}

let sub1 = new Sub1("sub1")
    ds1 = sub1.duplicate();  // 创建的对象类型为 Sub1
let sub2 = new Sub2("sub2"),
    ds2 = sub2.duplicate();  // 创建的对象类型为 Base

Symbol.species 返回的函数决定类的方法创建新实例时该实例的类型。

构造器中使用 new.target

使用 new 创建类实例时, new.target 的值为 new 的目标类型,也就是类。所以当使用 new 实例化类时,在构造器中 new.target 总存在值。

在基类的构造器中使用了 new.target 的前提下,用 new 实例化子类时,子类的构造器会调用基类的构造器,此时 new.target 的值是子类而不是基类,可能基类中 new.target 的使用在这种情况下会出现意料之外的结果。

参考

[1] Zakas, Understanding ECMAScript 6, 2017.

标签:name,09,constructor,let,基类,new,class,UES
From: https://www.cnblogs.com/xdreamc/p/16552483.html

相关文章

  • B3663 [语言月赛202209] Luogu Academic
    [语言月赛202209]LuoguAcademic题目描述七海在LA群中游走,获得了一个由英文小写字符组成的字符串SSS。七海想要知道,子串luogu在其中出现了多少次。提示:一个字......
  • UOJ#884. 【UR #27】509 号迷宫
    有一个显然的\(\mathcalO(n^2)\)DP。考虑利用组合数优化,只在满足纵坐标\(y|p\)的位置记录状态并转移。有障碍,需要做容斥。四种转移:线对线、点对点、线对点、点对线组合计数算明白了就简单了。代码#include<bits/stdc++.h>usingnamespacestd;constexprintN=......
  • 【异常错误】RTX 4090 nvcc fatal : Unsupported gpu architecture ‘compute_89‘
    https://mapengsen.blog.csdn.net/article/details/137865369?spm=1001.2101.3001.6650.3&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EYuanLiJiHua%7EPosition-3-137865369-blog-123348901.235%5Ev43%5Epc_blog_bottom_relevance_base8&depth_1......
  • Windows驱动开发涉及到许多重要的概念和技术,包括调试、进程管理、文件操作、注册表访
    Windows驱动开发涉及到许多重要的概念和技术,包括调试、进程管理、文件操作、注册表访问、系统调用、IRP(I/ORequestPacket)和锁原理。以下是对每个主题的简要介绍:调试Windows驱动程序的调试通常涉及使用调试器(如WinDbg)来分析驱动程序的运行时行为,包括查看内存、寄存器状态、......
  • css09 CSS Comments
    https://www.w3schools.com/css/css_comments.aspCSScommentsarenotdisplayedinthebrowser,buttheycanhelpdocumentyoursourcecode.CSSCommentsCommentsareusedtoexplainthecode,andmayhelpwhenyoueditthesourcecodeatalaterdate.Com......
  • [SDOI2009] Bill的挑战
    [SDOI2009]Bill的挑战题目信息题目描述Sheng_bill不仅有惊人的心算能力,还可以轻松地完成各种统计。在昨天的比赛中,你凭借优秀的程序与他打成了平局,这导致Sheng_bill极度的不满。于是他再次挑战你。这次你可不能输。这次,比赛规则是这样的:给出\(N\)个长度相同的字符串(由......
  • 2252309-介绍主流源代码管理工具--Github(举例说明具体使用--旅行+兼职平台)
    一、Github介绍目录1、简介2、特点3、优点4、缺点5、使用教程6、举例二、详细介绍1、简介(1)Github的产生:软件开发过程中会因源代码引发各种繁琐的问题,如版本备份(费空间,费时间)、版本混乱(因版本备份过多造成混乱,难以找回正确的想要版本)、代码冲突(团队开发过程中多人操作同......
  • request to https://registry.npm.taobao.org/cnpm failed, reason: certificate has
    换华为的,否则会出问题:cnpmconfgsetregistryhttps://mirrors.huaweicloud.com/repository/npm/npmERR!codeCERT_HAS_EXPIREDnpmERR!errnoCERT_HAS_EXPIREDnpmERR!requesttohttps://registry.npm.taobao.org/cnpmfailed,reason:certificatehasexpirednpmER......
  • vulhub-driftingblues3
    发现/robots.txt->/eventadmins/->/littlequeenofspades.html->/adminsfixit.php界面包含ssh日志,通过尝试发现ssh连接后会更新日志,使用php一句话木马ssh -l'<?phpsystem($_GET[\"cmd\"]);?>' 192.168.56.111在kali下运行此命令出现错误:~>>ssh-l�......
  • MySQL - [09] 正则表达式
    转载:https://mp.weixin.qq.com/s/7RavuYGs9SthX2pxGJppqw  select*fromt1wherenamerlike'^[a-zA-Z]+$';  一、简介正则表达式使用rlike作为模式匹配的关键字,其语法结构如下selectcolumn_namefromtable_namewherecolumn_namerlike'pattern';column_n......