我的编程空间,编程开发者的网络收藏夹
学习永远不晚

es6 class是不是语法糖

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

es6 class是不是语法糖

这篇文章主要介绍了es6 class是不是语法糖的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇es6 class是不是语法糖文章都会有所收获,下面我们一起来看看吧。

class是语法糖。原因:class是基于原型继承的实现,对语言的功能并没有什么影响,只是方便了语法的书写及阅读;class的本质是function,能够让对象原型的写法更加清晰,更像面向对象编程的语法。

本教程操作环境:windows7系统、ECMAScript 6版、Dell G3电脑。

ES6 class类——语法糖

class (类)作为对象的模板被引入,可以通过 class 关键字定义类。它的本质是函数(function),可以看作一个语法糖,让对象原型的写法更加清晰、更像面向对象编程的语法。

它的class和别的语言不一样,它依旧是基于原型继承的实现,对语言的功能并没有影响,只是方便了你的书写及阅读

为什么说ES6的class是语法糖

我们带着问题去阅读下文:

  • 为什么说ES6的class是语法糖?

  • class是原型的语法糖吗?

  • 那又是如何使用原型来实现class这一语法糖的呢?

1. 基于Prototype的OOP

先来看一个prototype的例子:

function Person (name, sex) {
	this.name = name
	this.sex = sex
}
 
function Man (name) {
	this.name = name
}
 
Man.prototype = new Person('', 'male')
 
let Jy = new Man('Jy')
 
console.log(Jy.name, Jy.sex) // Jy, male

这是我们使用原型的一个很简单的例子,Person具有名字和性别,Man是一个性别为男的Person,Jy是一个Man。我们先记住这一个例子,下面将使用class重写这个例子。

Tips: new, this等是Brendan Eich使之更像Java的OOP而加上的,有兴趣的读者可以自行查阅相关信息。

2. ES6 Class的OOP

class Person {
	constructor (name, sex) {
		this.name = name
		this.sex = sex
	}
}
 
class Man extends Person {
	constructor (name) {
		super('', 'male')
		this.name = name
	}
}
 
let Jy = new Man('Jy')
 
console.log(Jy.name, Jy.sex) // Jy, 'male'

我们通过重写这个例子,采用了class、constructor、extends、super 这些单词,接下来就具体来说说ES6规范中对它们做了什么。

3. 使用Prototype实现的Class OOP(ES6规范)

在ES6之前,JS对象其实就是属性的集合,而属性则是一组键值对(key, value),key可以是String or Symbol, value包括数据属性特征值和访问器特征值。

你说普通的属性还好,不还有对象下面的方法吗?怎么就变成了属性的集合呢?

其实在ES5规范中出现的method的定义是“function that is the value of a property”,是对象的函数属性而已,不能称之为方法,直到ES6出现,规范中才有Method Definitions。

我们能想到的在ES3有关OOP的东西: prototype、new、 this、 constructor、 instanceof, 甚至不是规范的 __proto__ 属性。

所幸的是在ES5中我们增加了很多方法来补全它,使之完备:

  • Object.defineProperty

  • Object.freeze

  • Object.create

  • Object.getPrototypeOf

  • Object.setPrototypeOf

  • isPrototypeOf

  • ......

再来看一段代码:

let obj = {
	name: 'Jy',
	speak () { // Note: it's not speak: function () {}
		console.log(this.name, super.name)
	}
}
 
obj.speak() // Jy, undefined
 
Object.setPrototypeOf(obj,  { name: 'super' })
 
obj.speak() // Jy, super
 
let speak = obj.speak
speak() // undefined, super

obj.speak在ES6中定义已经是Method了,它具有属性[[homeObject]],homeObject指向方法被调用的对象(代码中指的是obj), 它是绑定在对象中的Internal Slots,也就是你不能去修改,就相当于写死了。

那么homeObject有什么用呢?它跟super密切相关,当解析到super这一关键字的时候就会找homeObject的prototype。

简单来说,总结为下面两条公式:

  • let homeObj = Method[[HomeObject]] = obj

  • super = Object.getPrototypeOf(homeObj)

Note: homeObject是静态绑定在internal slots中的,而super是动态查找的。

讲完super,我们来讲讲extends和constructor

class A extends B { }
 
class A extends B {
	constructor (...args) {
		super(args)
	}
}
 
class C extends null { }

extends主要做了以下两件事:

  • Object.setPrototypeOf(A, B)

  • Object.setPrototypeOf(A.prototype, B.prototype)

如果父类是null, 则执行Object.setPrototypeOf(C.prototype, null)

上述代码的第一和第二部分区别在于有没有显示声明constructor, 那么这两段代码是否等价呢?答案是等价的。

规范中就是这么定义的:

代码的第三部分是继承了null, 它不会报语法错误,但是我们无法new一个C出来,原因是new的时候会调用null的constructor,而null没有constructor。

看到这里,ES6的class oop, 规范声明都是使用原型来操作,所以我们是不是可以说class是原型的语法糖了?

4. babel编译后的class

我们实际项目中多采用babel来编译ES6、7的代码,所以这节我们就来分析以下babel编译后的代码,其中会省略一些报错、类型检测的一些相关代码来更好地呈现使用原型来实现OOP的主题。

编译前:

class A extends B {}
 
console.log(new A)

编译后:

"use strict";
 
function _getPrototypeOf(o) {
  _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
    return o.__proto__ || Object.getPrototypeOf(o);
  };
  return _getPrototypeOf(o);
}
 
function _inherits(subClass, superClass) {
  if (typeof superClass !== "function" && superClass !== null) {
    throw new TypeError("Super expression must either be null or a function");
  }
  subClass.prototype = Object.create(superClass && superClass.prototype, {
    constructor: {
      value: subClass,
      writable: true,
      configurable: true
    }
  });
  if (superClass) _setPrototypeOf(subClass, superClass);
}
 
function _setPrototypeOf(o, p) {
  _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
    o.__proto__ = p;
    return o;
  };
  return _setPrototypeOf(o, p);
}
 
var A =
  
  function (_B) {
    _inherits(A, _B);
 
    function A() {
 
      return _getPrototypeOf(A).apply(this, arguments);
    }
 
    return A;
  }(B);
 
console.log(new A());

我们重点看_inherits 方法,跟我们上述说的extends做的两件事是一样的:

  • Object.setPrototypeOf(subClass, superClass)

  • Object.setPrototypeOf(subClass.prototype, superClass.prototype)

只不过它采用的是Object.create方法,这两个方法的区别可以去MDN上查看。

再看function A内部,其实就是执行了B的构造器函数来达到super(arguments)的效果, 这个与规范:如果没有显示声明constructor会自动加上constructor是一致的。

关于“es6 class是不是语法糖”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“es6 class是不是语法糖”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

es6 class是不是语法糖

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

class类是不是es6语法

本文小编为大家详细介绍“class类是不是es6语法”,内容详细,步骤清晰,细节处理妥当,希望这篇“class类是不是es6语法”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。class类是es6语法,是es6新增
2023-07-04

require是不是es6语法

本篇内容主要讲解“require是不是es6语法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“require是不是es6语法”吧!不是,require是CommonJS规范的模块化语法;而es6
2023-07-04

concat是不是es6语法

这篇文章主要介绍“concat是不是es6语法”,在日常操作中,相信很多人在concat是不是es6语法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”concat是不是es6语法”的疑惑有所帮助!接下来,请跟
2023-07-04

es6的class是不是严格模式

今天小编给大家分享一下es6的class是不是严格模式的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。是严格模式。es6类和模
2023-07-04

es6有哪些语法糖

es6语法糖有:1、对象字面量,是指以“{}”形式直接表示的对象;2、箭头函数,一种写匿名函数的新方法;3、解构赋值,允许按照一定的模式,从数组或对象中提取值,给变量进行赋值;4、剩余参数和拓展符;5、模板字符串;6、let和const声明语句。
2023-05-14

class是es5还是es6

class是es6新特性。在ES6中,class(类)作为对象的模板被引入,可以通过class关键字定义类;新的class写法让对象原型的写法更加清晰、更像面向对象编程的语法,也更加通俗易懂。类(class)是ECMAScript中新的基础性语法糖结构,虽然ES6类表面上看起来可以支持正式的面向对象编程,但实际上它背后使用的仍然是原型和构造函数的概念,让对象原型的写法更加清晰、
2022-11-22

es6语法糖怎么使用

本篇内容主要讲解“es6语法糖怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“es6语法糖怎么使用”吧!es6语法糖有:1、对象字面量,是指以“{}”形式直接表示的对象;2、箭头函数,一种
2023-07-05

什么是语法糖?Vue3.2中怎么使用语法糖?

Vue中怎么使用语法糖?下面本篇文章带大家了解一下语法糖,并介绍一下Vue3.2语法糖的使用方法,希望对大家有所帮助!
2022-11-28

es6语法是不是一种标准

本文小编为大家详细介绍“es6语法是不是一种标准”,内容详细,步骤清晰,细节处理妥当,希望这篇“es6语法是不是一种标准”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。es6语法是一种标准。ES6全称是ECMASc
2023-07-04

es6的class是干什么的

es6的class关键字用于快速地定义“类”;class的本质是function,它可以看作一个语法糖,让对象原型的写法更加清晰、更像面向对象编程的语法。提升class不存在变量提升,类的所有方法都定义在类的prototype属性上面,在类的实例上面调用方法,其实就是调用原型上的方法。
2022-11-22

class是es6的新特性吗

这篇文章主要讲解了“class是es6的新特性吗”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“class是es6的新特性吗”吧!class是es6新特性。在ES6中,class(类)作为对象
2023-07-04

编程热搜

目录