转载地址:https://www.cnblogs.com/sghy/p/8005857.html

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

  1. class Greet {
  2. constructor(x, y) {
  3. this.x = x;
  4. this.y = y;
  5. }
  6. sayHello() {
  7. console.log(this.x + " " + this.y)
  8. }
  9. }
  10. let a = new Greet("hello", "everybody");
  11. a.sayHello() //hello everybody

《注》:

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

类的实例对象:

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

Class表达式:

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

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

私有方法:

  • 利用Symbol值的唯一性
  1. const bar = Symbol('bar');
  2. const snaf = Symbol('snaf');
  3.  
  4. export default class myClass{
  5.  
  6. // 公有方法
  7. foo(baz) {
  8. this[bar](baz);
  9. }
  10.  
  11. // 私有方法
  12. [bar](baz) {
  13. return this[snaf] = baz;
  14. }
  15.  
  16. // ...
  17. };
  • 利用#标识:
  1. class Greet {
  2. constructor(x, y) {
  3. this.x = x;
  4. this.y = y;
  5. }
  6. #sayHello() {
  7. console.log(this.x + " " + this.y)
  8. }
  9. }

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

  1. class MyClass {
  2. constructor() {
  3. // ...
  4. }
  5. get prop() {
  6. return 'getter';
  7. }
  8. set prop(value) {
  9. console.log('setter: '+value);
  10. }
  11. }
  12.  
  13. let inst = new MyClass();
  14.  
  15. inst.prop = 123;
  16. // setter: 123
  17.  
  18. inst.prop
  19. // 'getter'

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

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

Class 的静态属性和实例属性

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

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

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

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

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

  1. class Point {
  2. }
  3.  
  4. class ColorPoint extends Point {
  5. }

supper:

  • 子类必须在constructor方法中调用super方法(子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工)
  1. class Point { /* ... */ }
  2.  
  3. class ColorPoint extends Point {
  4. constructor() {
  5. }
  6. }
  7.  
  8. let cp = new ColorPoint(); // ReferenceError
  • 如果子类没有定义constructor方法,这个方法会被默认添加
  1. class ColorPoint extends Point {
  2. }
  3.  
  4. // 等同于
  5. class ColorPoint extends Point {
  6. constructor(...args) {
  7. super(...args);
  8. }
  9. }
  • 在子类的构造函数中,只有调用super之后,才可以使用this关键字(子类实例的构建,是基于对父类实例加工,只有super方法才能返回父类实例)
  1. class Point {
  2. constructor(x, y) {
  3. this.x = x;
  4. this.y = y;
  5. }
  6. }
  7.  
  8. class ColorPoint extends Point {
  9. constructor(x, y, color) {
  10. this.color = color; // ReferenceError
  11. super(x, y);
  12. this.color = color; // 正确
  13. }
  14. }
  • super作为函数调用时,代表父类的构造函数。ES6 要求,子类的构造函数必须执行一次super函数。且只能用在子类的构造函数之中,用在其他地方就会报错
  1. class A {}
  2.  
  3. class B extends A {
  4. constructor() {
  5. super();
  6. }
  7. }  //super虽然代表了父类A的构造函数,但是返回的是子类B的实例
  • super作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。

a)普通方法中:

  1. class A {
  2. p() {
  3. return 2;
  4. }
  5. }
  6.  
  7. class B extends A {
  8. constructor() {
  9. super();
  10. console.log(super.p()); // 2
  11. }
  12. }  //指向父类的原型对象
  13.  
  14. let b = new B();

b) 静态方法中:

  1. class Parent {
  2. static myMethod(msg) {
  3. console.log('static', msg);
  4. }
  5.  
  6. myMethod(msg) {
  7. console.log('instance', msg);
  8. }
  9. }
  10.  
  11. class Child extends Parent {
  12. static myMethod(msg) {
  13. super.myMethod(msg);
  14. }
  15.  
  16. myMethod(msg) {
  17. super.myMethod(msg);
  18. }
  19. }
  20.  
  21. Child.myMethod(1); // static 1
  22.  
  23. var child = new Child();
  24. child.myMethod(2); // instance 2

浅谈ES6中的Class的更多相关文章

  1. 浅谈ES6中super关键字

    作用: super 关键字用于访问父对象上的函数. 语法: super([arguments]); // 访问父对象上的构造函数 super.functionOnParent([arguments]) ...

  2. 浅谈ES6中的Async函数

    转载地址:https://www.cnblogs.com/sghy/p/7987640.html 定义:Async函数是一个异步操作函数,本质上,Async函数是Generator函数的语法糖.asy ...

  3. 浅谈ES6中的Proxy

    Proxy是一个很有趣的对象,它能够修改某些操作的默认行为,等同于在语言层面做出修改,属于一种‘元编程’,即对编程语言进行编程. Proxy其实很好理解,就是在目标对象之前架设一层拦截,外界的访问都得 ...

  4. 浅谈ES6原生Promise

    浅谈ES6原生Promise 转载 作者:samchowgo 链接:https://segmentfault.com/a/1190000006708151 ES6标准出炉之前,一个幽灵,回调的幽灵,游 ...

  5. 浅谈JS中 var let const 变量声明

    浅谈JS中 var let const 变量声明 用var来声明变量会出现的问题: 1. 允许重复的变量声明:导致数据被覆盖 2. 变量提升:怪异的数据访问.闭包问题 3. 全局变量挂载到全局对象:全 ...

  6. 浅谈Java中的equals和==(转)

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str ...

  7. 浅谈Linux中的信号处理机制(二)

    首先谢谢 @小尧弟 这位朋友对我昨天夜里写的一篇<浅谈Linux中的信号处理机制(一)>的指正,之前的题目我用的“浅析”一词,给人一种要剖析内核的感觉.本人自知功力不够,尚且不能对着Lin ...

  8. 浅谈Java中的对象和引用

    浅谈Java中的对象和对象引用 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...

  9. 浅谈Java中的equals和==

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: String str1 = new String("hello"); String str2 = ...

随机推荐

  1. 自动化安装操作系统(Centos7+PXE+Cobbler+kickstart)

    一.简介 PXE称作是一种引导方式而不是安装方式似乎更加准确,PXE(Pre-boot Execution Environment)是由Intel设计的协议,它可以使计算机通过网络启动,但是有一个前提 ...

  2. linux作业--第十周

    1.在阿里云服务器搭建openv-p-n(有条件的同学再做) 2.通过编译.二进制安装MySQL5.7 编译安装MySQL5.7 安装相关包 yum -y install libaio numactl ...

  3. Linux网卡ifcfg-eth0配置详解

    DEVICE="eth1"                              网卡名称 NM_CONTROLLED="yes"            n ...

  4. tp5怎么防sql注入 xss跨站脚本攻击

    在 application/config.php 中有个配置选项 框架默认没有设置任何过滤规则,你可以是配置文件中设置全局的过滤规则 则会调用这些函数 自动过滤 // 默认全局过滤方法 用逗号分隔多个 ...

  5. EXSI6.7 中给虚拟机磁盘扩容

    [admin@localhost ~]$ sudo fdisk -l Disk /dev/sda: 214.7 GB, 214748364800 bytes, 419430400 sectors Un ...

  6. django的request对象方法初识

    1:request.post 拿到的是post请求发送过来的数据,可以将其看作是一个个的键值对 使用get方法可以通过key拿到值,如果该值是一个列表的话,get方法只能拿到列表的最后一个值,使用ge ...

  7. MATLAB探索初步问题汇总

    MATLAB命令窗口如果显示:尝试将SCRIPT normrnd作为函数执行:C:\User-- 出错sort 这类问题,一般是你的*.m文件的名与内置函数名重名,改一下文件名即可. 2.MATLAB ...

  8. 分布式 PostgreSQL 集群(Citus)官方安装指南

    单节点 Citus Docker (Mac 与 Linux) Docker 镜像仅用于开发/测试目的, 并且尚未准备好用于生产用途. 您可以使用一个命令在 Docker 中启动 Citus: # st ...

  9. 使用SymPy

    最近工作的原因,需要进行一些积分运算,通过一些搜索得知了SymPy,记录一下使用历程. 1. SymPy介绍 SymPy是关于Symbolic Mathematics的Python库,它旨在成为一个功 ...

  10. kubernetes更改coredns增加解析

    kubernetes更改coredns增加解析 k8s中coredns可以为全集群提供dns解析功能, 所以如果我们要手动增加dns解析, 只需在coredns中增加dns解析对即可 1. 编辑cor ...