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的基本语法的更多相关文章

  1. Javascript——ES6( ECMAScript 6.0)语法

    ES6( ECMAScript 6.0)语法 一.let/const与var的区别 var 会进行预解析,let/const不会 var可以声明两个重名的变量,let/const不能 var没有块级作 ...

  2. ES6 class的基本语法-学习笔记

    1.基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰.更像面向对象编程的语法而已. 类的内部所有定义的方法,都是 ...

  3. Sublime Es6教程2-基本语法

    2.基本语法 let, const, forEach,for of class, extends, super arrow functions, template string, destructur ...

  4. ES6 class(基本语法+方法)

    静态属性与静态方法 1. 不会被类实例所拥有的属性与方法 只是类自身拥有2. 只能通过类调用 静态方法与普通方法重名,不会冲突static 关键字(静态方法) 静态属性类名.属性名 = 属性值; 1. ...

  5. ES6之对象的语法糖

    本文介绍下ES6中对象的一些拓展功能. 这三个语法糖在实际的项目开发中经常会见到.

  6. es6的一些基本语法

    首先说一下什么是es6: ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准; let 和 const 命令 let的基本用法: 上面代码在代码块之中,分别用l ...

  7. es6几个新增语法的使用----数组

    //数组的累加方法 let arr=[1,2,3]; let sum=arr.reduce((prev,cur)=>{ return prev+cur; }) console.log(sum)/ ...

  8. es6函数的新语法

    函数的默认值 function(x,y=10){ //赋予了y就有了默认值为10,如果y赋值了,就回被覆盖,否则就是默认值10 变量已经有默认值了,所以不用再次用let或者const声明啦 }

  9. es6 和 python 语法比较

    http://www.linchaoqun.com/html/cms/content.jsp?id=1509528630774 Python3笔记:Python与ECMAScript部分语法对比 ht ...

随机推荐

  1. English Time And Date

    What's the Time in English? Explanation There are two common ways of telling the time. Formal but ea ...

  2. awt多线程聊天

    public class ChatServer { boolean started = false; ServerSocket serverSocket = null; public void sta ...

  3. [人工智能] 安装python jupyter

    1.  什么是python jupyter ? 简单的说,可以理解为一个IDE. http://jupyter.org/ 2.  安装python jupyter notebook http://ju ...

  4. java框架之SpringBoot(1)-入门

    简介 Spring Boot 用来简化 Spring 应用开发,约定大于配置,去繁从简,just run 就能创建一个独立的.产品级别的应用. 背景: J2EE 笨重的开发.繁多的配置.低下的开发效率 ...

  5. java框架之SpringBoot(4)-资源映射&thymeleaf

    资源映射 静态资源映射 查看 SpringMVC 的自动配置类,里面有一个配置静态资源映射的方法: @Override public void addResourceHandlers(Resource ...

  6. java之数据库连接池-dbcp&c3p0&dbutils

    介绍 因为数据库连接对象的创建比较消耗性能,所以可以在应用程序启动时就在内存中开辟一片空间(集合)存放多个数据库连接对象,后面需要连接时直接从该空间中取而不用新创建:使用完毕后归还连接(将连接重新放回 ...

  7. cds view join和association

    1:创建两张表:ztt_teacher01 和ztt_teacher02 用于 cds view中的join和association 2:创建两个cds view:ztt_teacher01_id_n ...

  8. 10个有趣的Python教程,附视频讲解+练手项目。

    从前的日色变得慢,车.马.邮件都慢 一生只够爱一门编程语言 从前的教程也好看,画面精美有样子 你看了,立马就懂了 Python最性感的地方,就在于它的趣味性和前沿性,学习Python,你总能像科技节的 ...

  9. 墨刀联合有赞Vant组件库,让你轻松设计出电商原型

    继上周新上线了简历模板之后,本周墨刀的原型模板库又欢喜地增添一名新成员! 有赞Vant组件库 (做电商的宝宝要捂嘴笑了)   Vant 组件库是有赞前端团队开源的一套基于Vue的UI组件库,目前版本收 ...

  10. linux tcp server

    这里分析两种模型 A: 来源于网络,http://bbs.chinaunix.net/thread-4067753-1-1.html,号称50万QPS B: 本人自己写的,我觉得性能上比上述的模型要好 ...