JavaScript ES6新的类继承特性学习笔记

来源:互联网 发布:excel两张表数据匹配 编辑:程序博客网 时间:2024/05/22 18:57

Javascript新标准ES6正式出来都一年多了,最近才有时间愿意集中精力研究下,发现有些新特性确实亮瞎了我的双眼,比如,最新的“类-实例”的支持,再比如模仿Python引入gennerator等等。下面和大家分享下我ES6类继承的学习笔记吧。

JavaScript的标准——ECMAScript在不断发展,最新版ECMAScript 2015标准(简称ES6)已经在2015年6月正式发布了。新版本的ES有很多亮点,其中一个亮点就是正式引入了class关键字,开始正式支持面向对象的“类-实例”方式了。

0x01 比较

以前JavaScript的对象模型是基于原型实现的,特点是简单,缺点是理解起来比传统的“类-实例”模型要困难,最大的缺点是继承的实现需要编写大量代码,并且需要正确实现原型链。
下面是利用原型实现类继承的一种方式:

    'use strict';        //动物原型         function Animal(props){             this.name=props.name||"未知";         }        Animal.prototype.eat=function(){            alert(this.name+"在吃东西...");        }        //继承动物的鸟        function Bird(props){            Animal.call(this,props);                this.type=props.type||”未知”;        }        function F(){}        F.prototype=Animal.prototype;        Bird.prototype=new F();        Bird.prototype.constructor=Bird;        Bird.prototype.fly=function(){            alert(this.name+"在飞...");        }

效果如下:

可见,为了实现类的继承,使用了中间量等大量辅助代码,废了多大功夫,不熟悉的人还不大理解。庆幸的是在ES6中,终于有了类似C++/PHP等语言那种真正意义上的“类-实例”模型了:

    'use strict';        class Animal{            //构造函数            constructor(props){                this.name=props.name||'未知';            }            eat(){                alert(this.name+"在吃东西...");            }        }        //class继承        class Bird extends Animal{            //构造函数            constructor(props){               //调用实现父类的构造函数                super(props);                this.type=props.type||"未知";            }            fly(){                alert(this.name+"在飞...");            }        }

效果如下:

效果一样,但是是不是瞬间有种回到PHP代码的赶脚??看起来还是那么熟悉的姿势。嘿嘿。。。

0x02 转换

ES6中的class用起来是蛮爽的,但是,由于出来的比较晚了,不是所有的主流浏览器都支持ES6滴,况且不少童鞋还在用IE6呢,那么岂不是咱写代码时不敢用啦?幸运的是有个Babel的工具,可以实现自动从ES6转换为ES5。具体安装和使用有篇博客写的不错,可以参考下:Babel安装
,其实还可以直接用在线方式实现代码的装换(Babel在线转换):

上面ES6代码转换的结果如下:

'use strict';        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;            };        }();        function _possibleConstructorReturn(self, call) {            if (!self) {                throw new ReferenceError("this hasn't been initialised - super() hasn't been called");            }            return call && (typeof call === "object" || typeof call === "function") ? call : self;        }        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;        }        function _classCallCheck(instance, Constructor) {            if (!(instance instanceof Constructor)) {                throw new TypeError("Cannot call a class as a function");            }        }        var Animal = function () {            //构造函数            function Animal(props) {                _classCallCheck(this, Animal);                this.name = props.name || '未知';            }            _createClass(Animal, [                {                    key: 'eat',                    value: function eat() {                        alert(this.name + "在吃东西...");                    }                }            ]);            return Animal;        }();        //class继承        var Bird = function (_Animal) {            _inherits(Bird, _Animal);            //构造函数            function Bird(props) {                _classCallCheck(this, Bird);                var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Bird).call(this, props));                _this.type = props.type || "未知";                return _this;            }            _createClass(Bird, [                {                    key: 'fly',                    value: function fly() {                        alert(this.name + "在飞...");                    }                }            ]);            return Bird;        }(Animal);

是不是又回到了基于原型实现的时代?这段代码就可以被一些老的浏览器支持了。

0x03 小结

现在,我们写javascript代码的时候,可以用一些ES6的新特性,比如class类继承等,然后再转换为ES5的标准,保证对一些老浏览器的兼容性。

1 0
原创粉丝点击