Class

基本用法


class n {
  constructor(x,y) {
    this.x = x;
    this.y = y;
    console.log(x,y)
  }

  proint() {
    console.log(' this is proint ')
  }
}

var newObject = new n(1,2);
// c {x: 1, y: 2}

newObject.proint();
// this is proint 

现在不用像以前.


function o(x,y) {
    this.x = x;
    this.y = y;
    console.log(x,y)
}

o.prototype.proint = function() {
    console.log(' this is proint ');
};

var oldObject = new o(1,2); //1,2

oldObject.proint() //this is proint

书中说这是语法糖.

也就是说。本质上依旧使用的是

ES5 版本的创建对象.

Class 不过一种简化的写法.

不过需要验证一下。 接下来的例子都会同时有两个版本.


n === n.prototype.constructor //true
o === o.prototype.constructor

newObject.constructor === n.prototype.constructor //true
oldObject.constructor === o.prototype.constructor //true

也就是这样.

为了说明他是语法糖.


Object.assign(n.prototype,{
    mytest:function() { console.log('mytest') }
});

n.mytest() //mytest

n.prototype.proint //proint() { console.log(' this is proint ') }

constructor

你不写那么 javascript 就会为你自动创建一个空的

constructor() {}

new n() 就是调用 constructor 返回一个实例.

所以你可以改变返回的实例.


class foo {
    constructor() {
        return { y : 1 };
    }
}

new foo() // { y : 1 }

类的实例对象

基本和ES5原型链基本一样.

this , prototype

以及

类的所有实例共享一个原型对象

完全是ES5的老内容.

不存在变量提升

我一直认为变量提升这种东西.

是你写代码不规范导致的.

不存在也就不存在吧.

Class的表达式

几种写法.


let n = class c {  } //只有在class 内部调用才能调用C

let n1 = class {  }

let n2 = new class { } //自执行相当于马上实例化.

私有方法

书中提到了3种方式.

  1. 前面加 **_** 下划线
  2. 将私有方法移出模块
  3. 用Symbol

前两种我表示都太垃圾..

第三种还有些意思

const bar = Symbol('bar');

const snaf = Symbol('snaf');

export default class myClass{

// 公有方法

foo(baz) {

thisbar;

}

// 私有方法

bar {

return this[snaf] = baz;

}

// ...

};

这样确实可以私有。

百度了一波。 发现大部分都是使用 Symbol

例子中 bar 依然暴露在外.

没办法彻底的私有. 因为 Symbol 你如何防止随意的使用呢?

这样反而不如。 function 来的ok


function() {
    var a1 = function() {};
    return {
        a : function() {
            return a1();
        }
    }
}

继承

基本用法


class c1n extends n {}

基本的继承就是这样。 啥都不写。 完全照搬父类方法.

继承父类的一切。 this & prototype

你也可以自己写点儿啥.

具体的跟 ES5 并没有什么区别

需要注意的点在于 super,这个关键字.

它在 构造函数(constructor) 中,就是直接调用父类的构造函数.

它在普通的方法中,就是想到父类的this

class c1n extends n {
   constructor(x,y,z) { super(x,y); this.z = z }

   print() {
        super.proint();
        console.log('child print')
   }
}

var o = new c1n(1,2,3);

o.print();

// this is proint
// child print

不调用父类的构造函数是无法创建自己的this

所以 super 是必须在构造函数中调用的。

当然如果你忘记了。 浏览器会自动为你调用。

前提是你参数没有问题.

类的prototype属性和__proto__属性


class c1n extends n { };

c1n.__proto__ === n;

c1n.prototype.__proto__ === n.prototype;

这种继承你完全可以自己模拟


Object.setPrototypeOf(c1n.prototype, n.prototype);

c1n.__proto__ = n;

就可以继承了.

Object.getPrototypeOf(c1n) === n

这样也可以获取父类.

super 关键字

super.

上面说过。 首先需要再 构造函数调用 super,调用父类的构造函数。

然后 super 会转变模式.

super 会指向父类的原型对象. 可以调用父类的方法.

super 引用当前子类的引用(this)


class a1 {
   constructor(x,y) {
      this.x = x;
      this.y = y;
   }

   p() { console.log(this.x,this.y); }
}

class a2 extends a1 {
   constructor(x,y) {
      super(x,y);

      this.x =  33;
   }

   p1() { super.p(); }
}

var o = new a2()

o.p1(); //33 undefined

所以 this.yundefined.

Extends 的继承目标

上面代码的A,只要是一个有prototype属性的函数,就能被B继承。由于函数都有prototype属性(除了Function.prototype函数),因此A可以是任意函数。

也就是说

只要你有 prototype 属性. 且是一个函数,那就可以被继承.

书中讲了3个特殊情况.

  1. 继承 Object 相当于Object 的一个复制

  2. class a {}

这种情况下,A作为一个基类(即不存在任何继承),就是一个普通函数,所以直接继承Funciton.prototype。但是,A调用后返回一个空对象(即Object实例),所以A.prototype.__proto__指向构造函数(Object)的prototype属性。

  1. class a extends null
class C extends null {
  constructor() { return Object.create(null); }
}

3.原生构造函数的继承

ES6 以前你并不能继承一些原生的对象.

Boolean()

Number()

String()

Array()

Date()

Function()

RegExp()

Error()

Object()

你并不能继承,去模拟它。

因为你不能继承到对象的构造函数 constructor.

但是 extends 可以

所以你可以完全继承一个 Array 来改造他.


class nArray extends Array {

    constructor(...args) {
        super(...args); //调用构造函数.
    }

    push(obj) {
        //可以开始改造.
    }

}

就是这样.

4. Class的取值函数(getter)和存值函数(setter)

可以有 get set. 虽然ES5 也有


class testClass {
   get p() { console.log('b') }
   set p(value) { console.log('a') }
}

5. Class的Generator方法


class testClass {

    * [Symbol.iterator]() { }

}

6. Class的静态方法


class Foo {
  static classMethod() {
    return 'hello';
  }
}

Foo.classMethod() // 'hello'

var foo = new Foo();
foo.classMethod()
// TypeError: foo.classMethod is not a function

就是静态类。 不用实例化就可以调用。

不过不能访问内部的东西。 可以用于某些设计模式.

ES6 不支持静态属性。 书中说 ES7 支持

8. new.target属性

new.target 能返回实例化的对象.

如果不是 new 实例化,就是 undefined.


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

这就是一个例子。

必须是 Person 实例化.

利用这个特点,可以写出不能独立使用、必须继承后才能使用的类。


class Shape {
  constructor() {
    if (new.target === Shape) {
      throw new Error('本类不能实例化');
    }
  }
}

class Rectangle extends Shape {
  constructor(length, width) {
    super();
    // ...
  }
}

var x = new Shape();  // 报错
var y = new Rectangle(3, 4);  // 正确

就是这样.

大概了解了一下。 基本是以前就有的概念。当然也有一些没有的概念.

可以在实际中运用一下再来复盘一下.

18. class的更多相关文章

  1. CSharpGL(18)分别处理glDrawArrays()和glDrawElements()两种方式下的拾取(ColorCodedPicking)

    CSharpGL(18)分别处理glDrawArrays()和glDrawElements()两种方式下的拾取(ColorCodedPicking) 我在(Modern OpenGL用Shader拾取 ...

  2. ABP(现代ASP.NET样板开发框架)系列之18、ABP应用层——权限验证

    点这里进入ABP系列文章总目录 ABP(现代ASP.NET样板开发框架)系列之18.ABP应用层——权限验证 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目 ...

  3. ASP.NET MVC5+EF6+EasyUI 后台管理系统(18)-权限管理系统-表数据

    系列目录 这一节,我们插入数据来看看数据流,让各位同学,知道这个权限表交互是怎么一个流程,免得大家后天雾里来雾里去首先我再解释一些表,SysUser和SysRole表不用解释了. SysRoleSys ...

  4. C#开发微信门户及应用(18)-微信企业号的通讯录管理开发之成员管理

    在上篇随笔<C#开发微信门户及应用(17)-微信企业号的通讯录管理开发之部门管理>介绍了通讯录的部门的相关操作管理,通讯录管理包括部门管理.成员管理.标签管理三个部分,本篇主要介绍成员的管 ...

  5. [MySQL Reference Manual] 18 复制

    18 复制 18 复制 18.1 复制配置 18.1.1 基于Binary Log的数据库复制配置 18.1.2 配置基于Binary log的复制 18.1.2.1 设置复制master的配置 18 ...

  6. Hihocoder 太阁最新面经算法竞赛18

    Hihocoder 太阁最新面经算法竞赛18 source: https://hihocoder.com/contest/hihointerview27/problems 题目1 : Big Plus ...

  7. grep-2.26 sed-4.2.2 awk-4.1.4 wget-1.18 pcregrep-8.39 pcre2grep-10.22 for windows 最新版本静态编译

    -------------------------------------------------------------------------------------------- grep (G ...

  8. 《C#本质论》读书笔记(18)多线程处理

    .NET Framework 4.0 看(本质论第3版) .NET Framework 4.5 看(本质论第4版) .NET 4.0为多线程引入了两组新API:TPL(Task Parallel Li ...

  9. Java随机生成18位身份证号

    package com.ihome.data; import java.text.SimpleDateFormat; import java.util.Calendar; import java.ut ...

  10. tornado学习笔记18 _RequestDispatcher 请求分发器

    根据Application的配置,主要负责将客户端的请求分发到具体的RequestHandler.这个类实现了HTTPMessageDelegate接口. 18.1 构造函数 定义: def __in ...

随机推荐

  1. 苹果 OS X 系统U盘重装-抹盘重装、系统盘制作

    鉴于前段时间系统出了点问题,然后直接将盘抹了,来个彻底干净的系统重装.这里敲下过程.(网络恢复太慢了,我整整一个晚上竟然没down下来,恼怒了,直接U盘装) First,系统盘制作: 1.首先需要有: ...

  2. 【代码笔记】iOS-用户发布后能保存崩溃

    一,工程图. 二,代码. AppDelegate.m #import "AppDelegate.h" #import "RootViewController.h" ...

  3. 探索逻辑事务 TransactionScope

    一.什么是TransactionScope? TransactionScope即范围事务(类似数据库中的事务),保证事务声明范围内的一切数据修改操作状态一致性,要么全部成功,要么全部失败回滚. MSD ...

  4. Mongodb 3.2 Manual阅读笔记:CH9 存储

    9. 存储 9. 存储 9.1 存储引擎 9.1.1 WiredTiger存储引擎 9.1.1.1 文档级别并发 9.1.1.2 快照和检查点 9.1.1.3 Journaling 9.1.1.4 压 ...

  5. 自制xml实现SQL动态参数配置

    此文章是基于 搭建SpringMVC+Spring+Hibernate平台 一. 准备工作 1. 点击此找到并下载 commons-digester3-3.2.jar 2. 点击此找到并下载 comm ...

  6. 3.raid基础应用

    raid分为软备份和硬备份 软备份主要用来实验 应备份用于生产环境 raid0(带区卷)    具有很高的数据传输率,没有数据的冗余  1块磁盘 raid1(镜像卷)  提供数据冗余,利用率低  2块 ...

  7. HTML5全屏(Fullscreen)API详细介绍

    // 整个页面 onclick=   launchFullScreen(document.documentElement); // 某个元素 launchFullScreen(document.get ...

  8. spring HttpInvoker相关学习资料

    官方文档 spring支持的几种RPC 用Http Invoker实现RCP客户端与后台的交互 Java HttpInvoker小试 Spring注解发布RMI/HTTPInvoker/Hessian ...

  9. Linux 文件系统分区基础

    文件系统就是管理设备,组织文件的一些结构和算法. /boot分区,它包含了操作系统的内核和在启动系统过程中所要用到的文件, 建这个分 区是有必要的,因为目前大多数的PC机要受到BIOS的限制,况且如果 ...

  10. 阿里技术协会好文推荐:Android绘制流程http://click.aliyun.com/m/8719/

    一.前言 1.1.C++界面库 MFC.WTL.DuiLib.QT.Skia.OpenGL.Android里面的画图分为2D和3D两种: 2D是由Skia 来实现的,3D部分是由OpenGL实现的. ...