MyException - 我的异常网
当前位置:我的异常网» Web前端 » babel是怎么解析es6 extends继承的

babel是怎么解析es6 extends继承的

www.MyException.Cn  网友分享于:2013-08-11  浏览:0次
babel是如何解析es6 extends继承的

   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 高级程序设计(第三版)》也有介绍:

defineProperty接收3个参数Object.defineProperty(对象名,属性名,{ 描述符 }),其中描述符对象属性必须是4个属性值,
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

文章评论

什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
程序员必看的十大电影
程序员必看的十大电影
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
程序员都该阅读的书
程序员都该阅读的书
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
总结2014中国互联网十大段子
总结2014中国互联网十大段子
每天工作4小时的程序员
每天工作4小时的程序员
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
程序员和编码员之间的区别
程序员和编码员之间的区别
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
为什么程序员都是夜猫子
为什么程序员都是夜猫子
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
我是如何打败拖延症的
我是如何打败拖延症的
编程语言是女人
编程语言是女人
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
旅行,写作,编程
旅行,写作,编程
漫画:程序员的工作
漫画:程序员的工作
如何成为一名黑客
如何成为一名黑客
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
我的丈夫是个程序员
我的丈夫是个程序员
Java程序员必看电影
Java程序员必看电影
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
那些争议最大的编程观点
那些争议最大的编程观点
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
一个程序员的时间管理
一个程序员的时间管理
程序员的鄙视链
程序员的鄙视链
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
鲜为人知的编程真相
鲜为人知的编程真相
程序员应该关注的一些事儿
程序员应该关注的一些事儿
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
 程序员的样子
程序员的样子
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
老程序员的下场
老程序员的下场
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有