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. C#开发微信门户及应用(18)-微信企业号的通讯录管理开发之成员管理

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

  4. [MySQL Reference Manual] 18 复制

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

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

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

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

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

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

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

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

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

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

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

  10. error while loading shared libraries: libmysqlclient.so.18: cannot open shared object file: No such file or directory

    zabbix3.2启动有如下报错: # service zabbix_server startStarting zabbix_server:  /home/zabbix-server/sbin/zab ...

随机推荐

  1. List&lt;T&gt;保存为XML文件

    今天我们学习怎样把List<T>写成一个XML文件保存起来.因为我们在做动态网站开发时,需要对一些不太常变化的数据产生为XML文件,让程序直接去读取,而不是每次是SQL数据库取. 为了解决 ...

  2. 【leetcode】Permutations II

    Permutations II Given a collection of numbers that might contain duplicates, return all possible uni ...

  3. swfobject.js视频播放插件

    在网页中经常会用到视频播放的功能,下面介绍一下swfobject.js的视频播放应用:html代码结构: <div id="video_content"></di ...

  4. PHP数组常用函数分类整理

    一.数组操作的基本函数数组的键名和值array_values($arr);  获得数组的值array_keys($arr);  获得数组的键名array_flip($arr);  数组中的值与键名互换 ...

  5. SQL Server 启用与禁止触发器

    启用: disable trigger trigger_name on {objectName | database_name | server}; 禁用: enable trigger trigge ...

  6. STM32使用串口1配合DMA接收不定长数据,减轻CPU载荷

    STM32使用串口1配合DMA接收不定长数据,减轻CPU载荷 http://www.openedv.com/thread-63849-1-1.html 实现思路:采 用STM32F103的串口1,并配 ...

  7. iOS App稳定性指标及监测

    一个App的稳定性,主要决定于整体的系统架构设计,同时也不可忽略编程的细节,正所谓"千里之堤,溃于蚁穴",一旦考虑不周,看似无关紧要的代码片段可能会带来整体软件系统的崩溃.尤其因为 ...

  8. 对Javascript到底了解多少,一测便知道

    笔者在这里附上一段代码,请读者思考一下程序的运行结果: console.log(a); //??? a(); var a=3; function a(){ console.log(10); } con ...

  9. 取消Fragment切换时间,Fragment+ViewPager静止滑动,去掉默认的滑动效果

    import android.content.Context; import android.support.v4.view.ViewPager; import android.util.Attrib ...

  10. DataContract 和 DataMember

    数据契约(DataContract) 服务契约定义了远程访问对象和可供调用的方法,数据契约则是服务端和客户端之间要传送的自定义数据类型. 一旦声明一个类型为DataContract,那么该类型就可以被 ...