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. oracle 数据库、实例、服务名、SID

    参考:http://www.zhetao.com/content240 在实际的开发应用中,关于Oracle数据库,经常听见有人说建立一个数据库,建立一个Instance,启动一个Instance之类 ...

  2. 对text字段聚合,没有设置fielddate所以出错

    http://192.168.60.26:9200/linewell_assets_mgt_es_yh_test/lw_devices/ _mapping { "properties&quo ...

  3. Redis实战经验及使用场景

    随着应用对高性能需求的增加,NoSQL逐渐在各大名企的系统架构中生根发芽.这里我们将为大家分享社交巨头新浪微博.传媒巨头Viacom及图片分享领域佼佼者Pinterest带来的Redis实践,首先我们 ...

  4. ionic3.x版本开发问题记录---使用Image Resizer打包报错问题

    按照官方文档安装和使用,最后在打包的时候报错 /platforms/android/src/info/protonet/imageresizer/ImageResizer.java:12: error ...

  5. ZBX_NOTSUPPORTED: Cannot obtain filesystem information: [13] Permission denied

    zabbix有默认两条自动发现规则,其中一条是自动发现已挂载文件系统,但笔者的三个挂载文件系统中两个监控成功了,一个失败 agentd端挂载情况: 仔细研究sdb1的挂载点,发现它是挂载在xiami用 ...

  6. JedisCluster简单使用

    项目中因为一些原因需要用到缓存,之前没有接触过,在此做一些简单的使用记录. 1.jedis在项目中依赖 <dependency> <groupId>redis.clients& ...

  7. expdp 字符集从ZHS16GBK到AL32UTF8

    源oracle数据库是GBK字符集,目标库是UTF8字符集,现在需要将源库的一个表空间数据导入到目标库.我的解决方法有点繁琐,首先直接导出源库的表空间 expdp trmuser/trmpass sc ...

  8. 2018-2019-1 20189203《Linux内核原理与分析》第八周作业

    第一部分 课本学习 ELF文件(目标文件)格式主要三种: 1)可重定向文件:文件保存着代码和适当的数据,用来和其他的目标文件一起来创建一个可执行文件或者是一个共享目标文件.(目标文件或者静态库文件,即 ...

  9. C#设计模式(8)——桥接模式(Bridge Pattern)(转)

    一.引言 这里以电视遥控器的一个例子来引出桥接模式解决的问题,首先,我们每个牌子的电视机都有一个遥控器,此时我们能想到的一个设计是——把遥控器做为一个抽象类,抽象类中提供遥控器的所有实现,其他具体电视 ...

  10. hive 基础

    Apache的顶级项目,(java) 2008年Facebook公司开源给Apache基金会 官网:http://hive.apache.org/ hive 将SQL转换成MapReduce程序,并将 ...