ES5和ES6中类的区别总结


Posted in Javascript onDecember 21, 2020

类定义与调用的区别

在 ES5 中主要是通过构造函数方式和原型方式来定义一个类,但是在 ES6 新引入了 class 关键字,使之具有了正式类的能力,类(class)是ECMAScript 中新的基础性语法糖结构。虽然 ES6 类表面上看起来可以支持正式的面向对象编程,但实际上它背后使用的仍然是原型和构造函数的概念。

使用 ES5 定义一个类并调用

function Person(name, age, job) {
 this.name = "Totora";
 this.age = 19;
 this.job = "student";
 this.sayName = function() {
  console.log(this.name);
 };
}
let person = new Person();
person.sayName();

使用 ES6 定义一个类并调用

ES6中有两种定义类的方式:类声明和类表达式

class Person {
 constructor() {
  this.name = "Totora";
  this.age = 19;
  this.job = "student";
 }
 sayName() {
  console.log(this.name);
 }
}
let person = new Person();
person.sayName();
//当我们使用typeof检测Person的类型时:
console.log(typeof Person); //function,它的本质仍然是函数

在调用类时,不管是ES5还是ES6,都必须使用new操作符来进行调用,不可以直接执行。

两者区别在于:

ES5这样调用不会报错,可以正常执行(因为ES5中的类和普通函数几乎没有本质上的区别)

function Person(name, age, job) {
 this.name = "Totora";
 this.age = 19;
 this.job = "student";
 this.sayName = function() {
  console.log(this.name);
 };
}
let person = Person();
console.log(person); //undefined

ES6会报错

class Person {
 constructor() {
  this.name = "Totora";
  this.age = 19;
  this.job = "student";
 }
 sayName() {
  console.log(this.name);
 }
}
let person =Person();
console.log(person);
person.sayName(); //Class constructor Person cannot be invoked without 'new'

变量提升

通过以下对比可以发现,当用class声明类执行时会报错,说明ES6中用class定义的类无法实现变量提升。

函数受函数作用域的限制,但是类受块作用域的限制

//变量提升
let person = new Person()
function Person(name, age, job) {
 this.name = "Totora";
 this.age = 19;
 this.job = "student";
 this.sayName = function() {
  console.log(this.name);
 };
}
person.sayName(); //Totora
let person = new Person();
class Person {
 constructor() {
  this.name = "Totora";
  this.age = 19;
  this.job = "student";
 }
 sayName() {
  console.log(this.name);
 }
}
person.sayName(); // Cannot access 'Person' before initialization

class中类的构成

类可以包含构造函数方法、实例方法、获取函数、设置函数、静态类的方法。但是空的类定义照样有效

//空类定义
class Foo {}
//有构造函数的类
class Bar {
 constructor() {}
}
//有获取函数的类
class Baz {
 get myBaz() {}
}
//有静态方法的类
class Qux {
 static myQux() {}
}

class中的静态方法

可以在类上定义静态方法。静态类成员在类定义中使用static关键字作为前缀,在静态成员中,this引用类自身;

与原型成员类似,静态成员每个类上只能有一个;

static声明的静态属性和方法都可以被子类继承。

class Person {
 constructor() {
  //添加到this的所有内容都会存在于不同的实例上
  this.locate = () => console.log('instance', this);
 }
 //定义在类的原型对象上
 locate() {
  console.log('prototype', this);
 }
 //定义在类本身上
 static locate() {
  console.log('class', this);
 }
}
let p = new Person();
p.locate(); //instance Person { locate: [Function (anonymous)] }
Person.prototype.locate(); //prototype {}
Person.locate(); //class [class Person]
class Person {
 static name() {
  this.job(); //此处的this指向类
 }
 static job() {
  console.log('Totora'); //不会出现在实例中
 }
 job() {
  console.log('student');
 }
}
Person.name(); //Totora

继承

ES5中的继承实质上是先创建子类的实例对象,再将父类的方法添加到this上(Parent.apply(this)),通过原型或构造函数机制来实现

ES6的继承实际上是先创建父类的实例对象this,然后再用子类的构造函数修改this。

ES6中类之间通过extends关键字,就可以继承任何拥有[[Construct]]和原型的对象,在很大程度上,这不仅i仅可以继承一个类,也可以继承普通的构造函数(保持向后兼容)

ES6中派生类的方法可以通过super关键字引用它们的原型,这个关键字只能在派生类中使用,而且仅限于类的构造函数、实例方法和静态方法的内部。在类构造函数中使用super可以调用父类构造函数。

//ES5中的继承
function parent(a,b) {
 this.a = a;
 this.b = b;
}
function child(c) {
 this.c = c;
}
parent.call(child, 1, 2); //子级来继承父级
child.prototype = new parent(1, 2);
//ES6中的继承
class parent {
 constructor(a, b) {
  this.a = a;
  this.b = b;
 }
 parentMethods() {
  return this.a + this.b
 }
}
class child extends parent {
 constructor(a, b, c) {
  super(a, b); //通过super调用父类
  this.c = c;
 }
 childMethods() {
  return this.c + ',' + super.parentMethods() //通过super实例化调用父类
 }
}
const point = new child(1, 2, 3);
console.log(point.childMethods());

总结

到此这篇关于ES5和ES6中类区别的文章就介绍到这了,更多相关ES5和ES6类的区别内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
用javascript实现自定义标签
May 08 Javascript
JavaScript Prototype对象
Jan 07 Javascript
JS 类型转换常见方法小结
May 31 Javascript
jquery.cookie用法详细解析
Dec 18 Javascript
完美实现仿QQ空间评论回复特效
May 06 Javascript
使用AngularJS和PHP的Laravel实现单页评论的方法
Jun 19 Javascript
学习javascript面向对象 理解javascript对象
Jan 04 Javascript
angularJS 如何读写缓冲的方法(推荐)
Aug 06 Javascript
AngularJS路由切换实现方法分析
Mar 17 Javascript
JavaScript实现身份证验证代码实例
Aug 26 Javascript
javascript实现京东快递单号的查询效果
Nov 30 Javascript
详解javascript脚本何时会被执行
Feb 05 Javascript
jQuery实现动态向上滚动
Dec 21 #jQuery
Vue组件简易模拟实现购物车
Dec 21 #Vue.js
ES6字符串的扩展实例
Dec 21 #Javascript
vue实现购物车的小练习
Dec 21 #Vue.js
Vue实现小购物车功能
Dec 21 #Vue.js
原生JS实现京东查看商品点击放大
Dec 21 #Javascript
基于javascript实现移动端轮播图效果
Dec 21 #Javascript
You might like
php下目前为目最全的CURL中文说明
2010/08/01 PHP
PHP表单验证的3个函数ISSET()、empty()、is_numeric()的使用方法
2011/08/22 PHP
ThinkPHP实现一键清除缓存方法
2014/06/26 PHP
mysql_connect localhost和127.0.0.1的区别(网络层阐述)
2015/03/26 PHP
php版微信公众平台接口参数调试实现判断用户行为的方法
2016/09/23 PHP
ThinkPHP模板标签eq if 中区分0,null,false的方法
2017/03/24 PHP
php实现JWT验证的实例教程
2020/11/26 PHP
Ext第一周 史上最强学习笔记---GridPanel(基础篇)
2008/12/29 Javascript
JavaScript类型转换方法及需要注意的问题小结(挺全面)
2010/11/11 Javascript
jQuery ajax请求返回list数据动态生成input标签,并把list数据赋值到input标签
2016/03/29 Javascript
js实现按钮控制带有停顿效果的图片滚动
2016/08/30 Javascript
利用Js的console对象,在控制台打印调式信息测试Js的实现
2016/11/26 Javascript
微信公众号开发 实现点击返回按钮就返回到聊天界面
2016/12/15 Javascript
微信小程序 标签传入数据
2017/05/08 Javascript
Vue使用枚举类型实现HTML下拉框步骤详解
2018/02/05 Javascript
vue + vuex todolist的实现示例代码
2018/03/09 Javascript
在vue-cli3.0 中使用预处理器 (Sass/Less/Stylus) 配置全局变量操作
2020/08/10 Javascript
[01:09:23]KG vs TNC 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
Python批量转换文件编码格式
2015/05/17 Python
Python实现SVN的目录周期性备份实例
2015/07/17 Python
对python创建及引用动态变量名的示例讲解
2018/11/10 Python
Python列表常见操作详解(获取,增加,删除,修改,排序等)
2019/02/18 Python
python2.7的flask框架之引用js&css等静态文件的实现方法
2019/08/22 Python
Python文件名匹配与文件复制的实现
2020/12/11 Python
用CSS3实现无限循环的无缝滚动的示例代码
2017/11/01 HTML / CSS
Clearly新西兰:购买眼镜、太阳镜和隐形眼镜
2018/04/26 全球购物
香港中原电器网上商店:Chung Yuen
2019/06/26 全球购物
全陪导游欢迎词
2014/01/17 职场文书
工商管理本科生求职信
2014/07/13 职场文书
党风廉正建设责任书
2015/01/29 职场文书
社区服务活动报告
2015/02/05 职场文书
2015年骨干教师工作总结
2015/05/26 职场文书
mysql主从复制的实现步骤
2021/10/24 MySQL
asyncio异步编程之Task对象详解
2022/03/13 Python
灵能百分百第三季什么时候来?
2022/03/15 日漫
在Oracle表中进行关键词搜索的过程
2022/06/10 Oracle