一、定义类(ES6的类,完全可以看做是构造函数的另一种写法)

class Greet {
constructor(x, y) {
this.x = x;
this.y = y;
}
sayHello() {
console.log(this.x + " " + this.y)
}
}
let a = new Greet("hello", "everybody");
a.sayHello() //hello everybody

《注》:

  • 以上定义的类如果用ES5的构造函数实现如下:
function Greet(x, y) {
this.x = x;
this.y = y;
this.sayHello = function () {
console.log(this.x + " " + this.y)
}
} let a = new Greet("hello", "everybody");
a.sayHello() //hello everybody
  • 类的数据类型就是函数,类本身就指向构造函数
typeof Greet; //function
Greet === Greet.prototype.constructor //true
  • 类的所有方法都定义在类的prototype属性上面
class Greet {
constructor() {...}
sayHello() {...}
sayHi(){...}
}
等同于
Greet
Greet.prototype = {
constructor() {},
sayHello() {},
sayHi() {},
};
constructor方法
  • 是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。
class Greet {
}
// 等同于
class Greet {
constructor() {}
}
  • constructor方法默认返回实例对象(即this),完全可以指定返回另外一个对象。
class Foo {
constructor() {
return Object.create(null);
}
} new Foo() instanceof Foo
// false

类的实例对象:

  • 实例的属性除非显式定义在其本身(即定义在this对象上),否则都是定义在原型上(即定义在class上)。
class Greet {
constructor(x, y) {
this.x = x;
this.y = y;
}
sayHello() {
console.log(this.x + " " + this.y)
}
}
let a = new Greet("hello", "everybody");
// x,y都是实例对象a自身的属性,因为定义在this上
a.hasOwnProperty('x') // true
a.hasOwnProperty('y') // true
//sayHello是原型对象的属性,因为定义在Greet上
a.hasOwnProperty('sayHello') // false
a.__proto__.hasOwnProperty('sayHello') // true
  • 类的所有实例共享一个原型对象
let a = new Greet("hello", "everybody");
let b = new Greet("hello", "everybody"); a.__proto__ === b.__proto__ //true

Class表达式:

const MyClass = class Me {
getClassName() {
return Me.name;
}
}; //类的名字是MyClass而不是Me,Me只在 Class 的内部代码可用,指代当前类。
//如果类的内部没用到的话,可以省略Me
const MyClass = class {
...
};

不存在变量提升:必须先定义类,再使用

私有方法:

  • 利用Symbol值的唯一性
const bar = Symbol('bar');
const snaf = Symbol('snaf'); export default class myClass{ // 公有方法
foo(baz) {
this[bar](baz);
} // 私有方法
[bar](baz) {
return this[snaf] = baz;
} // ...
};
  • 利用#标识:
class Greet {
constructor(x, y) {
this.x = x;
this.y = y;
}
#sayHello() {
console.log(this.x + " " + this.y)
}
}

Class 的取值函数(getter)和存值函数(setter):在“类”的内部可以使用getset关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为。

class MyClass {
constructor() {
// ...
}
get prop() {
return 'getter';
}
set prop(value) {
console.log('setter: '+value);
}
} let inst = new MyClass(); inst.prop = 123;
// setter: 123 inst.prop
// 'getter'

Class 的静态方法:加上static关键字,表示该方法不会被实例继承,而是直接通过类来调用

class Foo {
static classMethod() {
return 'hello';
}
} Foo.classMethod() // 'hello' var foo = new Foo();
foo.classMethod()
// TypeError: foo.classMethod is not a function
  • 如果静态方法包含this关键字,这个this指的是类,而不是实例
  • 父类的静态方法,可以被子类继承
  • 静态方法也是可以从super对象上调用的

Class 的静态属性和实例属性

  • 静态属性指的是 Class 本身的属性,即Class.propName,而不是定义在实例对象(this)上的属性,定义方法如下:
class MyClass {
static myStaticProp = 42; constructor() {
console.log(MyClass.myStaticProp); //
}
}
  • 类的实例属性可以用等式,写入类的定义之中
class MyClass {
myProp = 42; constructor() {
console.log(this.myProp); //
}
}

new.target 属性:如果构造函数不是通过new命令调用的,new.target会返回undefined

用来确定构造函数是怎么调用的。

function Person(name) {
if (new.target !== undefined) {
this.name = name;
} else {
throw new Error('必须使用 new 命令生成实例');
}
}

二、Class继承:通过extends关键字实现继承

class Point {
} class ColorPoint extends Point {
}

supper:

  • 子类必须在constructor方法中调用super方法(子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工)
class Point { /* ... */ }

class ColorPoint extends Point {
constructor() {
}
} let cp = new ColorPoint(); // ReferenceError
  • 如果子类没有定义constructor方法,这个方法会被默认添加
class ColorPoint extends Point {
} // 等同于
class ColorPoint extends Point {
constructor(...args) {
super(...args);
}
}
  • 在子类的构造函数中,只有调用super之后,才可以使用this关键字(子类实例的构建,是基于对父类实例加工,只有super方法才能返回父类实例)
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
} class ColorPoint extends Point {
constructor(x, y, color) {
this.color = color; // ReferenceError
super(x, y);
this.color = color; // 正确
}
}
  • super作为函数调用时,代表父类的构造函数。ES6 要求,子类的构造函数必须执行一次super函数。且只能用在子类的构造函数之中,用在其他地方就会报错
class A {}

class B extends A {
constructor() {
super();
}
}  //super虽然代表了父类A的构造函数,但是返回的是子类B的实例
  • super作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。

a)普通方法中:

class A {
p() {
return 2;
}
} class B extends A {
constructor() {
super();
console.log(super.p()); //
}
}  //指向父类的原型对象 let b = new B();

b) 静态方法中:

class Parent {
static myMethod(msg) {
console.log('static', msg);
} myMethod(msg) {
console.log('instance', msg);
}
} class Child extends Parent {
static myMethod(msg) {
super.myMethod(msg);
} myMethod(msg) {
super.myMethod(msg);
}
} Child.myMethod(1); // static 1 var child = new Child();
child.myMethod(2); // instance 2

ES6学习之Class的更多相关文章

  1. ES6学习目录

    前面的话 ES6是JavaScript语言的下一代标准,已经在 2015 年 6 月正式发布.它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言 为什么要学 ...

  2. es6学习笔记-class之继承

    继承 上一篇学习了class的概念,在es5时,对象的继承有好几种,原型链继承,借用构造函数继承,组合继承,原型式继承,寄生式继承以及寄生组合式继承,都是按照函数的形式去集成的,现在class也有它的 ...

  3. es6学习笔记-class之一概念

    前段时间复习了面向对象这一部分,其中提到在es6之前,Javasript是没有类的概念的,只从es6之后出现了类的概念和继承.于是乎,花时间学习一下class. 简介 JavaScript 语言中,生 ...

  4. javascript的ES6学习总结(第二部分)

    1.数组循环 介绍数组循环之前,先回顾一下ES5数组的循环 (1)数组遍历(代替普通的for):arr.forEach(callback(val,index,arr){todo}) //val是数组的 ...

  5. javascript的ES6学习总结(第一部分)

    ES6(ESNext学习总结——第一部分) ES6, 全称 ECMAScript 6.0 ,是 JavaScript 的下一个版本标准,2015.06 发版. ECMA每年6月份,发布一个版本 201 ...

  6. ES6学习笔记<五> Module的操作——import、export、as

    import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ...

  7. ES6学习笔记<四> default、rest、Multi-line Strings

    default 参数默认值 在实际开发 有时需要给一些参数默认值. 在ES6之前一般都这么处理参数默认值 function add(val_1,val_2){ val_1 = val_1 || 10; ...

  8. ES6学习笔记<三> 生成器函数与yield

    为什么要把这个内容拿出来单独做一篇学习笔记? 生成器函数比较重要,相对不是很容易理解,单独做一篇笔记详细聊一聊生成器函数. 标题为什么是生成器函数与yield? 生成器函数类似其他服务器端语音中的接口 ...

  9. ES6学习笔记<二>arrow functions 箭头函数、template string、destructuring

    接着上一篇的说. arrow functions 箭头函数 => 更便捷的函数声明 document.getElementById("click_1").onclick = ...

  10. ES6学习笔记<一> let const class extends super

    学习参考地址1  学习参考地址2 ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准.因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015:也 ...

随机推荐

  1. PAT 1053. 住房空置率 (20)

    在不打扰居民的前提下,统计住房空置率的一种方法是根据每户用电量的连续变化规律进行判断.判断方法如下: 在观察期内,若存在超过一半的日子用电量低于某给定的阈值e,则该住房为“可能空置”: 若观察期超过某 ...

  2. linux c编程:信号(二) alarm和pause函数

    使用alarm函数可以设置一个定时器,在将来的某个时刻该定时器超时.当定时器超时后,产生SIGALRM信号.如果忽略或不捕捉此信号,则其默认动作是终止调用该alarm函数的进程 #include< ...

  3. Call method 的使用

    SAP学习日志---Call method 的使用 以及常见错误 转载▼   可以通过以下方法 call method 1. 进入全局类中 找到方法,拖到程序中 2. 使用pattern 中的 AAB ...

  4. linux sort按照指定列排序

    sort怎样按指定的列排序0000 27189 41925425065f 15 419254250663 7 419254250675 5 419254250691 76 419254250693 2 ...

  5. Jooq比较偏的用法

    count public Integer count(Integer id) { return dslContext.selectCount().from(Tables.<table_name& ...

  6. CKeditor插件开发流程(二)SyntaxHighlighter

    CKEditor整合SyntaxHighlighter实现代码高亮显示 1,版本说明 CKEditor:ckeditor_4.0.1_standard.zipSyntaxHighlighter:syn ...

  7. 【七】MongoDB管理之分片集群介绍

    分片是横跨多台主机存储数据记录的过程,它是MongoDB针对日益增长的数据需求而采用的解决方案.随着数据的快速增长,单台服务器已经无法满足读写高吞吐量的需求.分片通过水平扩展的方式解决了这个问题.通过 ...

  8. PHP新写的大转盘抽奖源码

    中奖概率 抽奖大转盘演示:http://www.sucaihuo.com/php/3301.html function getRand($proArr, $proCount) { $result = ...

  9. EntityFramework 学习 一 Local Data

    DBSet的Local属性提供简单的从context上下文获取当前已经被跟踪的实体(实体不能被标记为Deleted状态) using System.Data.Entity; class Program ...

  10. Linux开发引导

    1.应用程序目录 /bin 用于存放启动系统时用到的程序 /usr/bin 用于存放用户使用的标准程序 /usr/local/bin 用于存放软件安装的程序 /sbin:/usr/sbin 用于存放系 ...