ES6 Class 可以通过extends
关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多,这跟JAVA中的继承比较类似。
class Anima{ constructor(name){ this.name = name } say(){ let a = 2 console.log(`my name is ${this.name}`) } } class Cat extends Anima{ constructor(name,age){ super(name); this.age =age; } eat(){ console.log(`i like fish...`) } }
我们先来回顾下es6之前的js继承实现,在《JavaScript 高级程序设计(第三版)》p162 中提到了有6种继承方式,组合继承算是比较常见了。
//父类 function Father(name){ this.name = name; } Father.prototype.say = function(){ console.log('my name is '+this.name); } //子类 function Son(name,age){ //继承父类属性 Father.call(this,name); this.age = age; } Son.prototype = new Father(); Son.prototype.hello = function(){ console.log('hello,my name is '+this.name+','+this.age+'years old'); }
相对于ES6中的extends明显繁琐很多,但是由于目前ES6在国内尚未大量普及,还有估计浏览器的兼容性,即使用到也会结合babel来转成ES5。那么babel是如何解析extends的呢?
http://babeljs.io/ babel在线转换,在这里可以实时看到babel是如何将es6转为es5的。
对于class,babel直接将它转为一个function
其中有个_classCallCheck函数用来检测Anima是被当作普通函数调用还是构造函数(类)来调用。
function _classCallCheck(instance, Constructor) { if (! (instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
而对于类中的方法,babel转换后通过_createClass函数来生成,
var _createClass = (function() { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function(Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
其中有个defineProperties函数,主要通过 Object.defineProperty来定义对象的方法,其中还定义了一系列的参数,这跟Anima.prototype.say = function(){...}作用其实是一样的。
_createClass(Anima, [{ key: "say", value: function say() { var a = 2; console.log("my name is " + this.name); } }]);
Object.defineProperty也是es5新的api,在《JavaScript 高级程序设计(第三版)》也有介绍:
wirtable : 是否可写,当为false时,对象属性值就无法改变
configurable : 字面意思 是否可注册,当它为false时,属性无法删除,及无法通过delete 删除对象属性,即使通过多次调 用Object.defineProperty()来修改configurable的值 也会受到限制
enumerable : 能否通过 for-in遍历属性
value : 设置属性值
接下来就是extends,对应的是_inherits函数
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
代码比较简单,寥寥几行,就是通过Object.create实现原型继承,让后让子类的constructor重新指向自己,但是这仅仅继承了父类的原型方法,ES6中会通过super关键字来调用父类的属性或者方法,
var _this = _possibleConstructorReturn(this, (Cat.__proto__ || Object.getPrototypeOf(Cat)).call(this, name));
这句话的作用就是Anima.call(this,name)。其中Object.getPrototypeOf返回对象的原型,例如:
function Pasta(grain, width) { this.grain = grain; this.width = width; } // Create an object from the pasta constructor. var spaghetti = new Pasta("wheat", 0.2); // Obtain the prototype from the object. var proto = Object.getPrototypeOf(spaghetti); alert(proto == Pasta.prototype);//true
总结:
babel将ES6的extends解析为组合继承,只不过babel使用了大量es5的api
相关推荐
本文将深入探讨如何使用Babel实现JS中的ES6 Class继承。 首先,我们需要了解ES6中的Class。Class是一种更接近传统面向对象编程的语法糖,它提供了一种更清晰的方式来定义构造函数和方法。比如: ```javascript ...
- 类与继承:`class MyClass extends BaseClass {}` - 模块导入导出:`import/export` - 声明式异步函数:`async/await` - 管理对象属性:`obj.{key} = value;` - 可计算属性名:`[expression] in object` - 默认...
2. **类与继承**:ES6提供了更接近传统面向对象编程的类和继承语法,使JavaScript代码更加易读易写。例如: ```javascript class Person { constructor(name) { this.name = name; } sayHello() { console....
babel-plugin-extends-error 问题: extends Error 。 使用babel编译代码时,堆栈跟踪不可用。 安装 npm install babel-plugin-extends-error --save 它要求您身边安装 。 只需npm install es6-error --save ,您就...
`class`关键字用于定义类,`extends`关键字用于实现继承。 3. **模板字符串**:使用反引号(``)定义的字符串,可以方便地进行字符串拼接,通过`${expr}`插入表达式的结果。 4. **解构赋值**:允许从数组或对象中...
- **类与继承**:ES6引入了class关键字,提供了更面向对象的语法,以及通过`extends`进行继承。 - **模块系统**:使用`export`导出模块,`import`导入模块,使得代码组织更加清晰。 - **Promise**:处理异步操作...
通天塔-101 通过学习 ES6 和 Babel。随机笔记我对模板字符串的第一印象是嗯。 但是它对于打印包含许多变量的字符串非常方便。 以某种方式extends和super让我想起了 Java ...... 模块可以导出const和function 。 ES6...
`class`关键字简化了构造函数、`prototype`和`super`的使用,`extends`关键字实现继承。 6. **Promise**:Promise是处理异步操作的一种方式,提供了链式调用,使异步代码更加清晰。 7. **模块系统**:通过`import`...
Babel是一个强大的转译器,它的主要作用是将ES6的高级语法转换成ES5,使得这些新特性可以在不完全支持ES6的环境中运行。使用Babel,开发者可以放心地在项目中应用ES6特性,而不用担心浏览器兼容性问题。 接下来,...
同时,通过`extends`关键字实现继承,`super`关键字用于调用父类的方法。 6. **模块(Module)**:ES6引入了原生的模块系统,使用`import`和`export`关键字来导入和导出模块,解决了以前通过全局变量共享代码的问题...
**ES6功能研讨会练习——Tower-of-babel-ws** 在编程世界中,JavaScript是一种不可或缺的脚本语言,尤其是在Web开发领域。随着技术的发展,ES6(ECMAScript 2015)版本的引入为JavaScript带来了许多新特性,极大地...
总结来说,Babel在JavaScript的继承方面扮演着关键角色,它使得开发者可以充分利用ES6的新特性,同时确保代码在广泛的环境和浏览器中保持兼容性。通过阅读`main.js`中的代码,我们可以学习到Babel如何将类和继承的...
- **类和继承**:基于原型的面向对象编程,如`class MyClass extends ParentClass { ... }`。 - **模板字符串**:用反引号(``)包围的字符串,可以方便地插入变量,如`${varName}`。 - **解构赋值**:方便地从数组或...
babel-es6 准系统使用起动机下ES6和JSX / 与从分叉快速开始$ npm run watch &$ npm start命令npm run build为生产而构建npm run watch在开发过程中自动重新编译npm start静态开发Web服务器入门代码import React from...
- `extends`:允许类之间的继承,提高了代码复用。 4. **箭头函数** - `(args) => expression`:箭头函数提供了一种更紧凑的函数定义方式,同时也解决了 `this` 的指向问题。 5. **解构赋值** - `let [a, b] = ...
5. **类和继承**:引入了面向对象编程的语法,如 `class` 关键字和 `extends` 实现继承。 6. **Promise**:用于异步操作的管理,解决回调地狱问题。 7. **模块系统**:通过 `import` 和 `export` 实现模块化,便于...
使用ES6 Class创建React组件,你需要继承React.Component基类,并实现render()方法。例如: ```jsx import React, { Component } from 'react'; class HelloWorld extends Component { render() { return <h1>...
当尝试用`require.ensure`加载ES6风格的React组件时,会遇到问题,因为Babel等转换工具通常不支持直接将ES6模块转换为可被`require`的格式。 **2. 解决方案** 为了解决这个问题,我们可以采取以下策略: - **添加...
3. **类与继承**:ES2015引入了基于原型的面向对象编程的语法糖,包括`class`关键字和`extends`关键字,简化了类的定义和继承。 4. **块级作用域**:通过`let`和`const`关键字,实现了块级作用域,解决了`var`声明...