ES5和ES6中类的区别总结

类定义与调用的区别

在 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类的区别内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • es5 类与es6中class的区别小结

    前言 在es5中主要是通过构造函数方式和原型方式来定义一个类,在es6中我们可以通过class来定义类,今天整理一下它们的区别. 关于es5中定义类的方式,可以看这一篇Js的'类',我们这里主要聊es5类和es6中class类的区别. 一.class类必须new调用,不能直接执行. class类执行的话会报错,而es5中的类和普通函数并没有本质区别,执行肯定是ok的. 二.class类不存在变量提升 图2报错,说明class方式没有把类的定义提升到顶部. 三.class类无法遍历它实例原型链上的

  • js es6系列教程 - 基于new.target属性与es5改造es6的类语法

    es5的构造函数前面如果不用new调用,this指向window,对象的属性就得不到值了,所以以前我们都要在构造函数中通过判断this是否使用了new关键字来确保普通的函数调用方式都能让对象复制到属性 function Person( uName ){ if ( this instanceof Person ) { this.userName = uName; }else { return new Person( uName ); } } Person.prototype.showUserNam

  • js定义类的方法示例【ES5与ES6】

    本文实例讲述了js定义类的方法.分享给大家供大家参考,具体如下: 以下是es5标准里定义类的方法: <script> function Point(x,y){ this.x=x; this.y=y; } Point.prototype.toString=function(){ return '('+this.x+', '+this.y+')'; } var point=new Point(1,2); console.log(point); </script> 运行结果: 上面这样用

  • ES5和ES6中类的区别总结

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

  • 分析ES5和ES6的apply区别

    目录 概述 函数签名 可选参数 非严格模式 异常处理 实际使用 总结 概述 众所周知, ES6 新增了一个全局.内建.不可构造的Reflect对象,并提供了其下一系列可被拦截的操作方法.其中一个便是Reflect.apply()了.下面探究下它与传统 ES5 的Function.prototype.apply()之间有什么异同. 函数签名 MDN 上两者的函数签名分别如下: Reflect.apply(target, thisArgument, argumentsList) function.a

  • React中ES5与ES6写法的区别总结

    前言 相信很多React的初学者都被ES6的问题迷惑:各路大神都建议我们直接学习ES6的语法(class Foo extends React.Component),然而网上搜到的很多教程和例子都是ES5版本的,所以很多人在学习的时候连照猫画虎都不知道怎么做.所以这篇文章就整理了一些ES5和ES6的写法对照表,希望大家以后读到ES5的代码,也能通过对照,在ES6下实现相同的功能.下面话不多说了,来看看详细的介绍吧. 模块 引用 在ES5里,如果使用CommonJS标准,引入React包基本通过re

  • 继承行为在 ES5 与 ES6 中的区别详解

    笔者注:一句话引发的基础知识回炉,基础不扎实,还要什么自行车 最近在看 React 方面的一些文章时,看到了这样一个问题,「为什么每个 class 中都要写 super, super 是做什么的?」, 刚看到这个问题时,直接就想到了继承行为在 javascript 中的表现.后面作者的一句话「super 不可以省略,省略的话会报错」.当时脑海中蹦出来一个念头,这个同学是不是写错了,super 不就是用来完成调用父类构造函数,将父类的实例属性挂在到 this 上吗?为什么不写还会报错? 后来自己亲

  • 详谈commonjs模块与es6模块的区别

    到目前为止,已经实习了3个月的时间了.最近在面试,在面试题里面有题目涉及到模块循环加载的知识.趁着这个机会,将commonjs模块与es6模块之间一些重要的的区别做个总结.语法上有什么区别就不具体说了,主要谈谈引用的区别. commonjs 对于基本数据类型,属于复制.即会被模块缓存.同时,在另一个模块可以对该模块输出的变量重新赋值. 对于复杂数据类型,属于浅拷贝.由于两个模块引用的对象指向同一个内存空间,因此对该模块的值做修改时会影响另一个模块. 当使用require命令加载某个模块时,就会运

  • 在ES5与ES6环境下处理函数默认参数的实现方法

    函数默认值是一个很提高鲁棒性的东西(就是让程序更健壮) MDN关于函数默认参数的描述:函数默认参数允许在没有值或undefined被传入时使用默认形参. ES5 使用逻辑或||来实现 众所周知,在ES5版本中,并没有提供的直接方法供我们我们处理函数默认值 所以只能够自己去增强函数的功能,一般会这么来做: function doSomething (name, age) { name = name || 'default name' age = age || 18 console.log(name

  • ES5 模拟 ES6 的 Symbol 实现私有成员功能示例

    本文实例讲述了ES5 模拟 ES6 的 Symbol 实现私有成员功能.分享给大家供大家参考,具体如下: ES6 中有类语法,定义类变得简单了 class Person { constructor(name) { this._name = name; } get name() { return this._name; } } 然而,并没有提供私有属性.比如上面的 Person 其实是希望在构造的时候传入 name,之后不允许修改了.不过,由于没有私有属性,所以难免有人会这样干: Person j

  • JavaScript设计模式之原型模式分析【ES5与ES6】

    本文实例讲述了JavaScript设计模式之原型模式.分享给大家供大家参考,具体如下: 从设计模式的角度讲,原型模式是用于创建对象的一种模式,若需要创建一个对象,一种方法是先指定其类型,然后通过类来创建这个对象,另一种方法是通过原型来创建,不必关心对象的具体类型,而是找到一个对象,然后通过克隆来创建一个一模一样的对象. ES5提供了Object.create(obj)方法来克隆对象,在不支持Object.create(obj)方法的浏览器中,可以使用以下代码: Object.create = O

随机推荐