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 相关文章推荐
jQuery学习笔记之jQuery选择器的使用
Dec 22 Javascript
jQuery + Flex 通过拖拽方式动态改变图片的代码
Aug 03 Javascript
Ubuntu 11.10 安装Node.js的方法
Nov 30 Javascript
再谈javascript面向对象编程
Mar 18 Javascript
THREE.JS入门教程(3)着色器-下
Jan 24 Javascript
jquery实现每个数字上都带进度条的幻灯片
Feb 20 Javascript
jQuery之日期选择器的深入解析
Jun 19 Javascript
js简单实现根据身份证号码识别性别年龄生日
Nov 29 Javascript
在Js页面通过POST传递参数跳转到新页面详解
Aug 25 Javascript
jQuery实现每隔一段时间自动更换样式的方法分析
May 03 jQuery
vue-vuex中使用commit提交mutation来修改state的方法详解
Sep 16 Javascript
基于JS判断对象是否是数组
Jan 10 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常见错误:SSL错误、bool(false)
2011/12/28 PHP
ThinkPHP模板引擎之导入资源文件方法详解
2014/06/18 PHP
PHP生成各种常见验证码和Ajax验证过程
2016/01/10 PHP
PHP面向对象程序设计(OOP)之方法重写(override)操作示例
2018/12/21 PHP
phpstorm 配置xdebug的示例代码
2019/03/31 PHP
强悍无比的WEB开发好助手FireBug(Firefox Plugin)
2007/01/16 Javascript
Confirmer JQuery确认对话框组件
2010/06/09 Javascript
js下通过prototype扩展实现indexOf的代码
2010/12/08 Javascript
JQuery扩展插件Validate 1 基本使用方法并打包下载
2011/09/05 Javascript
封装的jquery翻页滚动(示例代码)
2013/11/18 Javascript
jquery中get,post和ajax方法的使用小结
2014/02/04 Javascript
多种方法实现load加载完成后把图片一次性显示出来
2014/02/19 Javascript
jQuery实现表单步骤流程导航代码分享
2015/08/28 Javascript
js实现网站最上边可关闭的浮动广告条代码
2015/09/04 Javascript
jQuery使用$获取对象后检查该对象是否存在的实现方法
2016/09/04 Javascript
Vue.js动态组件解析
2016/09/09 Javascript
jquery easyui DataGrid简单示例
2017/01/23 Javascript
jquery.cookie.js的介绍与使用方法
2017/02/09 Javascript
JS中this的指向以及call、apply的作用
2018/05/06 Javascript
python登录QQ邮箱发信的实现代码
2013/02/10 Python
django1.11.1 models 数据库同步方法
2018/05/30 Python
Django模板导入母版继承和自定义返回Html片段过程解析
2019/09/18 Python
python 利用turtle库绘制笑脸和哭脸的例子
2019/11/23 Python
Spy++的使用方法及下载教程
2021/01/29 Python
html5 postMessage解决跨域、跨窗口消息传递方案
2016/12/20 HTML / CSS
美国从事品牌鞋类零售的连锁店:Famous Footwear
2016/08/25 全球购物
澳大利亚在线床零售商:Bedworks
2020/09/01 全球购物
AURALog面试题软件测试方面
2013/10/22 面试题
小学生考试获奖感言
2014/01/30 职场文书
导游个人求职信范文
2014/03/23 职场文书
责任心演讲稿
2014/05/14 职场文书
离婚协议书范本样本
2014/08/19 职场文书
学院党委班子四风问题自查报告及整改措施
2014/10/25 职场文书
教师群众路线教育实践活动学习笔记
2014/11/05 职场文书
党员个人总结范文
2015/02/14 职场文书
Java基础-封装和继承
2021/07/02 Java/Android