在之前的文章中我们讲过原型,原型链和原型链继承的文章,在 ES6 中为我们提供了更为方便的 class,我们先来看一下下面的例子:

 function Person(name) {
//构造函数里面的方法和属性
this._name = name;
this.getName = function () {
console.log(this._name);
};
this.setName = function (name) {
this._name = name;
};
} var p = new Person("zhangsan");
p.getName(); // zhangsan
p.setName("lisi");
p.getName(); // lisi

在上面的代码中我们利用构造函数做了一个可以获取姓名和修改姓名的操作。在 ES6 中我们可以这样写:

 class Person {
//类的构造函数,实例化的时候执行,new的时候执行
constructor(name) {
this._name = name;
}
getName() {
console.log(this._name);
}
setName(name) {
this._name = name
}
} var p = new Person('zhangsan'); p.getName(); // zhangsan
p.setName('lisi');
p.getName(); // lisi

在 ES6 中,我们可以定义一个 class 类,在勒种需要写一个 constructor 的构造函数,然后就可以像之前那样进行代码编写,这么写看起来似乎并没有省多少事,我们再来看下面的代码:

 function Person(name) {
//构造函数里面的方法和属性
this._name = name;
this.getName = function () {
console.log(this._name);
}
} //原型链上面的属性和方法可以被多个实例共享
Person.prototype._age = 30;
Person.prototype.getInfo = function () {
console.log(this._name, this._age);
}; function Foo(name, age) {
//对象冒充实现继承
Person.call(this, name, age);
} Foo.prototype = new Person(); //实例方法是通过实例化来调用的,静态是通过类名直接调用
var p = new Foo('zhangsan', 20);
p.getName(); // zhangsan
p.getInfo(); // zhangsan 30 //静态属性和方法
Person.instance = "静态属性";
Person.staticFunction = function () {
console.log('静态方法');
};
//执行静态属性和方法
console.log(Person.instance); // 静态属性
Person.staticFunction(); // 静态方法

我们在构造函数 Person 中定义 _name 属性和 getName() 的方法,同时在 Person 的原型链上增加了 _age 的属性和 getInfo() 的方法。我们这时定义一个 Foo 的方法,利用 call 方法进行对象冒充实现继承,如果我们注释掉第 20 行的代码,在运行到第 25 行时程序会报错 TypeError: p.setName is not a function,这时由于对象冒充继承无法继承原型链上的属性和方法,即 Person.prototype 上的属性和方法。如果我们注释掉第 17 行,则第 24 行输出 undefined,第 25 行输出 undefined 30,这时由于原型链继承可以继承构造函数里面的属性和方法,但是实例化子类的时候没法给父类传参。所以我们的 Foo 方法如果既想继承父类属性和方法,又想继承父类原型链上的属性和方法,就得使用原型链继承和对象冒充继承混合的方式。

另外我们可以直接在 Person 的构造函数上加静态属性和方法,即第 27 行以后。

接下来我们看一下 ES6 为我们提供的 class 类方法如何实现

 class Person {
constructor(name) {
this._name = name;
}
getName() {
console.log(this._name);
}
getInfo() {
console.log(this._name, this._age);
}
} class Foo extends Person {
constructor(name, age) {
//实例化子类的时候把子类的数据传给父类
super(name);
this._age = age;
}
getInfo() {
console.log("重写getInfo-->", this._name, this._age);
}
static staticFunction() {
console.log("Foo 的静态方法")
}
} var p = new Foo('zhangsan', 30);
p.getName(); // zhangsan
p.getInfo(); // 重写getInfo--> zhangsan 30 Foo.staticFunction(); //Foo 的静态方法 //静态属性和方法
Person.instance = "静态属性";
Person.staticFunction = function () {
console.log('Person 的静态方法');
};
//执行静态属性和方法
console.log(Person.instance); // 静态属性
Person.staticFunction(); // Person 的静态方法

在 ES6 中,我们可以通过 extends 关键字来使子类 Foo 继承父类 Person 的属性和方法,属性需要在 constructor 构造函数内通过 super 关键字来继承,同时我们也可以重写父类的方法 getInfo,这样看起来我们的代码更加工整简介。

同时我们既可以通过像 ES5 那样向 class 类中添加静态属性和方法,也可以通过关键字 static 向 class 类中添加静态属性和方法。

以上就是 ES6 中 class 类的基本使用方法,接下来我们看一下通过 class 类实现的单例模式:

class DB {
constructor() {
console.log('实例化会触发构造函数');
this.connect();
}
connect() {
console.log('连接数据库');
}
find() {
console.log('查询数据库');
}
} var db1 = new DB();
db1.find();
// 实例化会触发构造函数
// 连接数据库
// 查询数据库
var db2 = new DB();
db2.find();
// 实例化会触发构造函数
// 连接数据库
// 查询数据库

如上代码,我们定义了一个 Db 的 class 类来模拟后台数据库的连接,按照上面的代码运行的话,我们在需要跟后台建立连接的地方,都需要创建出一个实例 DB,这样就出现一个问题,我们每次连接数据库都是需要耗费时间的,这显然不是很友好的,如果我们把代码改成下面这样:

 class DB {
static getInstance() { /*单例*/
if (!DB.instance) {
DB.instance = new DB();
}
return DB.instance;
}
constructor() {
console.log('实例化会触发构造函数');
this.connect();
}
connect() {
console.log('连接数据库');
}
find() {
console.log('查询数据库');
}
} var db1 = DB.getInstance();
db1.find();
// 实例化会触发构造函数
// 连接数据库
// 查询数据库
var db2 = DB.getInstance();
db2.find();
// 查询数据库

我们在 class 类中加入了一个静态方法 getInstance,在该方法里先判断是否存在 instance 的静态属性,如果没有的话就给 instance 静态属性天际一个 new DB() 的实例,然后 return DB.instance,这样我们在实例化 DB 类的时候不直接实例化,而是调用 DB 的 getInstance 静态方法,这样在第一次调用的时候发现 DB 中没有 instance 这个静态属性,进入 if 判断中实例化 DB,然后走 constructor 的构造函数,就建立了数据库的连接,当我们再次调用 DB.getInstance 静态方法的时候,DB 类里已经有了 instance 的静态属性,所以 if 判断语句不执行,不再走 constructor 构造函数,直接对数据库进行操作就可以了,这种方式我我们就叫做单例模式。

javascript ES6 新特性之 class的更多相关文章

  1. javascript ES6 新特性之 扩展运算符 三个点 ...

    对于 ES6 新特性中的 ... 可以简单的理解为下面一句话就可以了: 对象中的扩展运算符(...)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中. 作用类似于 Object.assign() ...

  2. JavaScript ES6 新特性详解

    JavaScript ES6 带来了新的语法和新的强大功能,使您的代码更现代,更易读 const ,  let and var 的区别: const , let 是 ES6 中用于声明变量的新关键字. ...

  3. javascript ES6 新特性之 let

    let的作用是声明变量,和var差不多. let是ES6提出的,在了解let之前,最好先熟悉var的原理. JavaScript有一个机制叫“预解析”,也可以叫“提升(Hoisting)机制”.很多刚 ...

  4. JavaScript ES6新特性介绍

    介绍 ES6:ECMScript6 首先,一个常见的问题是,ECMAScript 和 JavaScript 到底是什么关系? ECMAScript是一个国际通过的标准化脚本语言: JavaScript ...

  5. javascript ES6 新特性之 Promise,ES7 async / await

    es6 一经推出,Promise 就一直被大家所关注.那么,为什么 Promise 会被大家这样关注呢?答案很简单,Promise 优化了回调函数的用法,让原本需要纵向一层一层嵌套的回调函数实现了横向 ...

  6. javascript ES6 新特性之 解构

    解构的作用是可以快速取得数组或对象当中的元素或属性,而无需使用arr[x]或者obj[key]等传统方式进行赋值 var arr = [1, 2, 3]; //传统方式 var a = arr[0], ...

  7. ES6新特性概览

    本文基于lukehoban/es6features ,同时参考了大量博客资料,具体见文末引用. ES6(ECMAScript 6)是即将到来的新版本JavaScript语言的标准,代号harmony( ...

  8. Atitit js版本es5 es6新特性

    Atitit js版本es5 es6新特性 Es5( es5 其实就是adobe action script的标准化)1 es6新特性1 Es5( es5 其实就是adobe action scrip ...

  9. ES6新特性:Proxy代理器

    ES6新特性:Proxy: 要使用的话, 直接在浏览器中执行即可, node和babel目前还没有Proxy的polyfill;,要使用的话,直接在浏览器中运行就好了, 浏览器的兼容性为:chrome ...

随机推荐

  1. Django day03之学习知识点

    今日是路由层学习: 3.路由匹配 3.1 正则表达式的特点: 一旦正则表达式能够匹配到内容,会立刻结束匹配关系 直接执行对应的函数.相当于采用就近原则,一旦找到就不再继续往下走了 重点: 正则表达式开 ...

  2. 《Java基础知识》Java常量的申明和使用

    常量就是从程序开始运行到结束都不变的量.在 Java 程序设计中,使用关键字“final”来声明一个常量,例如下面的程序代码. 这里的 x 是一个常量,但是是在某个方法内的常量,也可以称为成员常量(作 ...

  3. Linux命令-grep,sed,awk

    grep (global search regular expression[RE] and print out the line) 正则表达式全局搜索并将行打印出来 在文件中查找包含字符串" ...

  4. UWP 打开系统设置面板

    由于UWP各种权限管理的比较严格,所以在执行某一个特殊的操作之前,最好先申请一下相应的权限,以便告知用户你使用了这个权限,而且可以有效的避免App崩溃. 比如你想让用户手动打开麦克风权限,那么可以执行 ...

  5. javascript for循环+异步请求导致请求顺序不一致

    工作中遇到一个问题 for循环,再把循环出来的ID再进行二次请求 这就导致一个问题 请求结果返回顺序不一致 原因:异步请求会把回调事件放入微任务事件队列,宏任务执行完毕再执行微任务,具体参考事件队列机 ...

  6. Vue ES6箭头函数使用总结

    Vue ES6箭头函数使用总结   by:授客 QQ:1033553122   箭头函数 ES6允许使用“箭头”(=>)定义函数: 函数不带参数 定义方法:函数名称 = () => 函数体 ...

  7. 使用Advanced Installer打包工具如何设置是否安装预安装程序包

    要保证我们的程序能在目标机器上正常运行,便需要保证目标机器上提供了程序运行的必要组件. 而在使用Advanced Installer打包工具制作程序安装包时,我们可以通过配置“需求-运行环境-程序包- ...

  8. Docker浅析

    1.简介 Docker是一个开源的应用容器引擎:是一个轻量级容器技术: Docker支持将软件编译成一个镜像:然后在镜像中各种软件做好配置,将镜像发布出去,其他使用者可以直接使用这个镜像: 运行中的这 ...

  9. Appium(五):Desired Capabilities

    1. Desired Capabilities Desired Capabilities简单来说就是一组设置,这些设置可以让测试脚本控制Appium的运行行为.下面就逐个对Desired Capabi ...

  10. CSDN屏蔽广告

    CSDN俨然是一家广告网站了,各种广告层出不穷,且毫无底线.经常性的展示一些植发.防脱的广告,实在影响心情.另外,在复制内容的时候,会通过js给你带上一段来源,对于版权保护这是好事儿,但是对于直接复制 ...