es6 class的基本语法
ES5以及之前的版本,没有类的概念,但是聪明的JavaScript开发者,为了实现面向对象,创建了特殊的近类结构。
ES5中创建类的方法:新建一个构造函数,定义一个方法并且赋值给构造函数的原型。
- 'use strict';
- //新建构造函数,默认大写字母开头
- function Person(name) {
- this.name = name;
- }
- //定义一个方法并且赋值给构造函数的原型
- Person.prototype.sayName = function () {
- return this.name;
- };
- var p = new Person('eryue');
- console.log(p.sayName() // eryue
- );
ES6 class类
ES6实现类非常简单,只需要类声明。
类声明
如果你学过java,那么一定会非常熟悉这种声明类的方式。
- class Person {
- //新建构造函数
- constructor(name) {
- this.name = name //私有属性
- }
- //定义一个方法并且赋值给构造函数的原型
- sayName() {
- return this.name
- }
- }
- let p = new Person('eryue')
- console.log(p.sayName()) // eryue
和ES5中使用构造函数不同的是,在ES6中,我们将原型的实现写在了类中,但本质上还是一样的,都是需要新建一个类名,然后实现构造函数,再实现原型方法。
私有属性:在class中实现私有属性,只需要在构造方法中定义this.xx = xx。
类声明和函数声明的区别和特点
1、函数声明可以被提升,类声明不能提升。
2、类声明中的代码自动强行运行在严格模式下。
3、类中的所有方法都是不可枚举的,而自定义类型中,可以通过Object.defineProperty()手工指定不可枚举属性。
4、每个类都有一个[[construct]]的方法。
5、只能使用new来调用类的构造函数。
6、不能在类中修改类名。
类表达式
类有2种表现形式:声明式和表达式。
- //声明式
- class B {
- constructor() {}
- }
- //匿名表达式
- let A = class {
- constructor() {}
- }
- //命名表达式,B可以在外部使用,而B1只能在内部使用
- let B = class B1 {
- constructor() {}
- }
类是一等公民
JavaScript函数是一等公民,类也设计成一等公民。
1、可以将类作为参数传入函数。
- //新建一个类
- let A = class {
- sayName() {
- return 'eryue'
- }
- }
- //该函数返回一个类的实例
- function test(classA) {
- return new classA()
- }
- //给test函数传入A
- let t = test(A)
- console.log(t.sayName()) // eryue
2、通过立即调用类构造函数可以创建单例。
- let a = new class {
- constructor(name) {
- this.name = name
- }
- sayName() {
- return this.name
- }
- }('eryue')
- console.log(a.sayName()) // eryue
访问器属性
类支持在原型上定义访问器属性。
- class A {
- constructor(state) {
- this.state = state
- }
- // 创建getter
- get myName() {
- return this.state.name
- }
- // 创建setter
- set myName(name) {
- this.state.name = name
- }
- }
- // 获取指定对象的自身属性描述符。自身属性描述符是指直接在对象上定义(而非从对象的原型继承)的描述符。
- let desriptor = Object.getOwnPropertyDescriptor(A.prototype, "myName")
- console.log("get" in desriptor) // true
- console.log(desriptor.enumerable) // false 不可枚举
可计算成员名称
可计算成员是指使用方括号包裹一个表达式,如下面定义了一个变量m,然后使用[m]设置为类A的原型方法。
- let m = "sayName"
- class A {
- constructor(name) {
- this.name = name
- }
- [m]() {
- return this.name
- }
- }
- let a = new A("eryue")
- console.log(a.sayName()) // eryue
生成器方法
回顾一下上一章讲的生成器,生成器是一个返回迭代器的函数。在类中,我们也可以使用生成器方法。
- class A {
- *printId() {
- yield 1;
- yield 2;
- yield 3;
- }
- }
- let a = new A()
- let x = a.printId()
- x.next() // {done: false, value: 1}
- x.next() // {done: false, value: 2}
- x.next() // {done: false, value: 3}
这个写法很有趣,我们新增一个原型方法稍微改动一下。
- class A {
- *printId() {
- yield 1;
- yield 2;
- yield 3;
- }
- render() {
- //从render方法访问printId,很熟悉吧,这就是react中经常用到的写法。
- return this.printId()
- }
- }
- let a = new A()
- console.log(a.render().next()) // {done: false, value: 1}
静态成员
静态成员是指在方法名或属性名前面加上static关键字,和普通方法不一样的是,static修饰的方法不能在实例中访问,只能在类中直接访问。
- class A {
- constructor(name) {
- this.name = name
- }
- static create(name) {
- return new A(name)
- }
- }
- let a = A.create("eryue")
- console.log(a.name) // eryue
- let t = new A()
- console.log(t.create("eryue")) // t.create is not a function
继承与派生类
我们在写react的时候,自定义的组件会继承React.Component。
- class A extends Component {
- constructor(props){
- super(props)
- }
- }
A叫做派生类,在派生类中,如果使用了构造方法,就必须使用super()。
- class Component {
- constructor([a, b] = props) {
- this.a = a
- this.b = b
- }
- add() {
- return this.a + this.b
- }
- }
- class T extends Component {
- constructor(props) {
- super(props)
- }
- }
- let t = new T([2, 3])
- console.log(t.add()) //
关于super使用的几点要求:
1、只可以在派生类中使用super。派生类是指继承自其它类的新类。
2、在构造函数中访问this之前要调用super(),负责初始化this。
- class T extends Component {
- constructor(props) {
- this.name = 1 // 错误,必须先写super()
- super(props)
- }
- }
3、如果不想调用super,可以让类的构造函数返回一个对象。
类方法遮蔽
我们可以在继承的类中重写父类的方法。
- class Component {
- constructor([a, b] = props) {
- this.a = a
- this.b = b
- }
- //父类的add方法,求和
- add() {
- return this.a + this.b
- }
- }
- class T extends Component {
- constructor(props) {
- super(props)
- }
- //重写add方法,求积
- add() {
- return this.a * this.b
- }
- }
- let t = new T([2, 3])
- console.log(t.add()) //
静态成员继承
父类中的静态成员,也可以继承到派生类中。静态成员继承只能通过派生类访问,不能通过派生类的实例访问。
- class Component {
- constructor([a, b] = props) {
- this.a = a
- this.b = b
- }
- static printSum([a, b] = props) {
- return a + b
- }
- }
- class T extends Component {
- constructor(props) {
- super(props)
- }
- }
- console.log(T.printSum([2, 3])) //
派生自表达式的类
很好理解,就是指父类可以是一个表达式。
内建对象的继承
有些牛逼的人觉得使用内建的Array不够爽,就希望ECMA提供一种继承内建对象的方法,然后那帮大神们就把这个功能添加到class中了。
- class MyArray extends Array { }
- let colors = new MyArray()
- colors[0] = "1"
- console.log(colors) // [1]
Symbol.species
该用法我还没有接触过,目前只知道在内建对象中使用了该方法,如果在类中调用this.constructor,使用Symbol.species可以让派生类重写返回类型。
在构造函数中使用new.target
new.target通常表示当前的构造函数名。通常我们使用new.target来阻止直接实例化基类,下面是这个例子的实现。
- class A {
- constructor() {
- //如果当前的new.target为A类,就抛出异常
- if (new.target === A) {
- throw new Error("error haha")
- }
- }
- }
- let a = new A()
- console.log(a) // error haha
总结
本章只有一个知识点,那就是class的使用,最开始的声明class,到后面的继承派生类,都是非常常用的写法,还有静态成员的使用。
es6 class的基本语法的更多相关文章
- Javascript——ES6( ECMAScript 6.0)语法
ES6( ECMAScript 6.0)语法 一.let/const与var的区别 var 会进行预解析,let/const不会 var可以声明两个重名的变量,let/const不能 var没有块级作 ...
- ES6 class的基本语法-学习笔记
1.基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰.更像面向对象编程的语法而已. 类的内部所有定义的方法,都是 ...
- Sublime Es6教程2-基本语法
2.基本语法 let, const, forEach,for of class, extends, super arrow functions, template string, destructur ...
- ES6 class(基本语法+方法)
静态属性与静态方法 1. 不会被类实例所拥有的属性与方法 只是类自身拥有2. 只能通过类调用 静态方法与普通方法重名,不会冲突static 关键字(静态方法) 静态属性类名.属性名 = 属性值; 1. ...
- ES6之对象的语法糖
本文介绍下ES6中对象的一些拓展功能. 这三个语法糖在实际的项目开发中经常会见到.
- es6的一些基本语法
首先说一下什么是es6: ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准; let 和 const 命令 let的基本用法: 上面代码在代码块之中,分别用l ...
- es6几个新增语法的使用----数组
//数组的累加方法 let arr=[1,2,3]; let sum=arr.reduce((prev,cur)=>{ return prev+cur; }) console.log(sum)/ ...
- es6函数的新语法
函数的默认值 function(x,y=10){ //赋予了y就有了默认值为10,如果y赋值了,就回被覆盖,否则就是默认值10 变量已经有默认值了,所以不用再次用let或者const声明啦 }
- es6 和 python 语法比较
http://www.linchaoqun.com/html/cms/content.jsp?id=1509528630774 Python3笔记:Python与ECMAScript部分语法对比 ht ...
随机推荐
- RFID系统 免费开源代码 开发,分享[申明:来源于网络]
RFID系统 免费开源代码 开发,分享[申明:来源于网络] 地址:http://www.codeforge.cn/s/0/RFID%E7%B3%BB%E7%BB%9F
- Linux命令 printf
定长: $ printf '%s\t%s\t%s\t%s\t%s\t\n' $(cat printf.txt) # %s 表示一个不固定长度的字符串:printf不是管道命令,因此需要通过类似cat的 ...
- python文件派生
import time class Foo: x = 1 def __init__(self, y): self.y = y def __getattr__(self, item): # 没有的情况下 ...
- 记一次ADG备库归档目录满导致的延时处理
报错如下,原因是存放传过来的归档的目录+HWAREDODG满了,MRP进程无法应用归档,我在手动传了几个归档之后发现不是GAP,select * from V$ARCHIVE_GAP 显示没有GAP. ...
- office 2016密钥
Office 2016 Pro Plus Retail 版激活密钥:[Key]:3XJTG-YNBMY-TBH9M-CWB2Y-YWRHH[Key]:6TCQ3-NBBJ2-RTJCM-HFRKV-G ...
- webdriver入门-Java
webdriver入门-Java 如何用webdriver打开一个浏览器,我们常用的浏览器有firefox和IE两种,firefox是selenium支持得比较成熟的浏览器,很多新的特性都会在fi ...
- docker安装和基础操作
docker安装 yum install docker 配置镜像下载加速器 curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh ...
- JMeter-充值-生成随机数
1.随机数,orderId每次需要变化,需要用到随机数 验证生成的随机数:
- C#设计模式(3)——工厂方法模式(转)
C#设计模式(3)——工厂方法模式 一.引言 在简单工厂模式中讲到简单工厂模式的缺点,有一点是——简单工厂模式系统难以扩展,一旦添加新产品就不得不修改简单工厂方法,这样就会造成简单工厂的实现逻辑过 ...
- hive 基础
Apache的顶级项目,(java) 2008年Facebook公司开源给Apache基金会 官网:http://hive.apache.org/ hive 将SQL转换成MapReduce程序,并将 ...