在之前的文章中我们讲过原型,原型链和原型链继承的文章,在 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. Label自适应高度的用法及设置倒角

    UILabel *label = [[UILabel alloc] init]; //根据内容动态计算label的高度 label.text = @"Sent when the applic ...

  2. GHOST CMS - Package.json

    Package.json The package.json file is a set of meta data about a theme. package.json 文件是一组关于主题的元数据. ...

  3. Web基础了解版04-XML-Tomcat-Http

    XML 什么是XML - Tomcat - Http XML:eXtensible Markup Language (可扩展标记语言). XML 是一种标记语言,很类似 HTML. XML 的设计宗旨 ...

  4. win10: 搭建FTP服务器

    新建用户,可以设置多个用户,给予不同的权限 ftp创建完成后,新用户创建完成后,我们回到计算机管理-Internet Information Services(IIS)管理器来管理我们的FTP站点,点 ...

  5. 函数式响应式编程 - Functional Reactive Programming

    我们略过概念,直接看函数式响应式编程解决了什么问题. 从下面这个例子展开: 两个密码输入框,一个提交按钮. 密码.确认密码都填写并一致,允许提交:不一致提示错误. HTML 如下: <input ...

  6. Vue基础系列(五)——Vue中的指令(中)

    写在前面的话: 文章是个人学习过程中的总结,为方便以后回头在学习. 文章中会参考官方文档和其他的一些文章,示例均为亲自编写和实践,若有写的不对的地方欢迎大家和我一起交流. VUE基础系列目录 < ...

  7. Appium(十):元素定位(加强版)

    1. 元素定位 写完上一篇元素定位的博客,发现实用性基本为零.这几天真的烦死我了,一直在找资料,还去看了一遍appium官网文档.最后结合着selenium的定位方法,测试出几种可行的元素定位方法. ...

  8. python3数据分析,安装学习

    python3数据分析,安装学习 转载注明来源: 本文链接 来自osnosn的博客,写于 2019-09-26. 为了简单.安装 anaconda3 就好啦. 因为安装原版python3,用pip安装 ...

  9. C#/.Net开发入门篇(3)——console类的输入输出

    相信看了我上一篇文章的小伙伴们都知道console这个类的最基本的2个方法了吧,下去练习过的小伙伴应该能知道4个方法. 那么下面我们就来介绍一下上期没有介绍完的另外2个方法Console.WriteL ...

  10. pycharm查看函数用法,参数信息的设置方法

    在编写python程序时,常常会遇到一些不太常见的函数,有时候又不想去百度,那么,使用pycharm设置快速显示函数的参数和用法,这个方法十分快捷方便. step1. file -> setti ...