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. node.js xtemplate的使用实例

    工程下安装XTemplate并使用它的方法实例说明: 1.安装xtpl npm install xtpl xtemplate --save 2.在views目录添加test.xtpl文件,其内容为 t ...

  2. Android调用webservice的例子

    1.需要一个ksoap2-android-assembly-2.5.2-jar-with-dependencies.jar的架包. 2.需要知道webservice的命名空间 // WSDL文档中的命 ...

  3. SQL优化技术分析-2:SQL书写的影响

    1.同一功能同一性能不同写法SQL的影响. 如一个SQL在A程序员写的为 Select * from zl_yhjbqk B程序员写的为 Select * from dlyx.zl_yhjbqk(带表 ...

  4. [Erlang 0127] Term sharing in Erlang/OTP 上篇

    之前,在 [Erlang 0126] 我们读过的Erlang论文 提到过下面这篇论文: On Preserving Term Sharing in the Erlang Virtual Machine ...

  5. DBMS_NETWORK_ACL_ADMIN

    DBMS_NETWORK_ACL_ADMIN学习 转载 http://blog.sina.com.cn/s/blog_4f925fc30102e2se.html 标签: oracle it 分类: 数 ...

  6. Scala基础语法 (一)

    如果你之前是一名 Java 程序员,并了解 Java 语言的基础知识,那么你能很快学会 Scala 的基础语法. Scala 与 Java 的最大区别是:Scala 语句末尾的分号 ; 是可选的. 我 ...

  7. ajaxFileUpload插件

    关键词: $.ajaxFileUpLoad(); data status dataType 参考资料: http://www.cnblogs.com/kissdodog/archive/2012/12 ...

  8. MySQL 一致性读 深入研究

    一致性读,又称为快照读.使用的是MVCC机制读取undo中的已经提交的数据.所以它的读取是非阻塞的. 相关文档:http://dev.mysql.com/doc/refman/5.6/en/innod ...

  9. rsync同步架构

    1.1 rsync服务器端配置 1.1.1 查看服务器端rsync版本 1.1.2 创建配置文件 默认安装好rsync程序后,并不会自动创建rsync的主配置文件,需要手工来创建,其主配置文件为“/e ...

  10. Linux shell脚本编程(一)

    Linux shell脚本编程: 守护进程,服务进程:启动?开机时自动启动: 交互式进程:shell应用程序 广义:GUI,CLI GUI: CLI: 词法分析:命令,选项,参数 内建命令: 外部命令 ...