ES5 中的仿类结构
在ES5以前js并不存在类的概念,与类相接近的写法是,创建一个构造器,然后将方法指派到该构造器的原型上。这种方式通常被称为创建一个自定义类型。
类的声明
基本的类声明
类声明以 class 关键字开始,其后是类的名称;剩余部分的语法看起来就像对象字面量中的方法简写,并且在方法之间不需要使用逗号。
自有属性( Own properties ):该属性出现在实例上而不是原型上,只能在类的构造器或方法内部进行创建。在本例中, name 就是一个自有属性。建议应在构造器函数内创建所有可能出现的自有属性,这样在类中声明变量就会被限制在单一位置(有助于代码检查)。
为何要使用类的语法
尽管类与自定义类型之间有相似性,但仍然要记住一些重要的区别:
1. 类声明不会被提升,这与函数定义不同。类声明的行为与 let 相似,因此在程序的执行到达声明处之前,类会存在于暂时性死区内。
2. 类声明中的所有代码会自动运行在严格模式下,并且也无法退出严格模式。
3. 类的所有方法都是不可枚举的,这是对于自定义类型的显著变化,后者必须用Object.defineProperty() 才能将方法改变为不可枚举。
4. 类的所有方法内部都没有 [[Construct]] ,因此使用 new 来调用它们会抛出错误。
5. 调用类构造器时不使用 new ,会抛出错误。
6. 试图在类的方法内部重写类名,会抛出错误。
类表达式
基本的类表达式
类声明和类表达式都不会被提升,所以使用类表达式还是类声明只是代码风格的不同。
具名类表达式
在下例具名表达式中,PersonClass2相当于在类的内部使用const来定义的类的一个不同的名称。只在类的内部使用。
作为一级公民的类
在编程中,能被当作值来使用的就称为一级公民( first-class citizen ),意味着它能作为参数传给函数、能作为函数返回值、能用来给变量赋值。 JS的函数就是一级公民(它们有时又被称为一级函数)。ES6 延续了传统,让类同样成为一级公民。所以类可以以很多方式被引用。比如,作为参数传入函数;立即调用构造函数;
访问器属性
自有属性需要在类构造器中创建,而类还允许你在原型上定义访问器属性。为了创建一个getter ,要使用 get 关键字;创建 setter 用相同方式,只是要换用 set 关键字。
Object.getOwnPropertyDescriptor 函数 :获取指定对象的自身属性描述符。自身属性描述符是指直接在对象上定义(而非从对象的原型继承)的描述符。
Object.getOwnPropertyDescriptor(object, propertyname) //(属性对象,属性名称)
需计算的成员名
无须使用标识符,而是用方括号来包裹一个表达式。
生成器方法
在类中,可以将任意的方法变成一个生成器。也可以使用 Symbol.iterator 来定义生成器方法,从而定义出类的默认迭代器。
1 2 3静态成员
在ES5之前,通常在构造器上添加额外的方法来模拟静态成员。ES6中可以直接使用static 来为类添加静态成员。
ES5 ES6使用派生类进行继承
ES5 ES6如果派生类指定了构造器,就需要使用 super() ,否则会造成错误。若你选择不使用构造器, super() 方法会被自动调用,并会使用创建新实例时提供的所有参数。
使用 super() 时需牢记以下几点:
1. 你只能在派生类中使用 super() 。若尝试在非派生的类(即:没有使用 extends关键字的类)或函数中使用它,就会抛出错误。
2. 在构造器中,你必须在访问 this 之前调用 super() 。由于 super() 负责初始化this ,因此试图先访问 this 自然就会造成错误。
3. 唯一能避免调用 super() 的办法,是从类构造器中返回一个对象。
屏蔽类方法:派生类中的方法总是会屏蔽基类的同名方法。
继承静态成员:如果基类包含静态成员,那么这些静态成员在派生类中也是可用的。
从表达式中派生类
ES6 可以从表达式中派生类,只要表达式能够返回一个具有 [[Construct]] 属性以及原型的函数,就可以使用extends。extends 后面能接受任意类型的表达式。(比如,可以动态的决定需要集成的类)
继承内置对象
在 ES5 的传统继承中, this 的值会先被派生类(例如 MyArray )创建,随后基类构造器(例如 Array.apply() 方法)才被调用。这意味着 this 一开始就是 MyArray 的实例,之后才使用了 Array 的附加属性对其进行了装饰。
在 ES6 基于类的继承中, this 的值会先被基类( Array )创建,随后才被派生类的构造器( MyArray )所修改。结果是 this 初始就拥有作为基类的内置对象的所有功能,并能正确接收与之关联的所有功能。
Symbol.species 属性
Symbol.species 知名符号被用于定义一个能返回函数的静态访问器属性。每当类实例的方法(构造器除外)必须创建一个实例时,前面返回的函数就被用为新实例的构造器。
Array,ArrayBuffer ,Map,Promise,RegExp,Set,类型化数组。上述内置类型都定义了 Symbol.species
在类构造器中使用 new.targe
可以使用 new.target 来创建一个抽象基类(一种不能被实例化的类)。
网友评论