typescript和es6区别 类写constructor和不写constructor有什么区别

  这是一个JavaScript面向对象系列的文章,本篇文章主要讲概述,介绍面向对象,后面计划还会有5篇文章,讲抽象、封装、继承、多态,最后再来一个综合。

  说实话,写JavaScript面向对象的文章实在是太多了,网上一搜一大堆,很多书里面也介绍的很详细。但作者当初在学习面向对象的时候还是非常困难,特别是在习惯了面向过程编程的情况下,不知道大家有没有这个感受。

  作者分析了一下其中的原因,恐怕是因为里面涉及的概念太多:原型、原型链、继承、thisconstructorcall等等,这些都是要了解的。一介绍起来就像是拔出萝卜带出一大堆泥,知识点之间耦合度太高,一点都不符合面向对象封装的特点。

  所以作者在这一系列的文章中不准备介绍上面的这些概念,只会说这些东西在这里有什么用。作者会假定读者对这些概念一无所知,并且也不奢求读者读完这些文章后就对面向对象有非常深入的了解。

  这一系列的文章的定位就是quickstart,介绍JavaScript面向对象最常用的东西,让读者读完之后就能立马上手,仿照里面的demo写出面向对象风格的代码,等用的多了再回头去深入学习其中的原理,我相信这时候会容易的多。

  想了解更多?抱歉,看书去吧,《JavaScript高级程序设计》《JavaScript权威指南》里面讲的比作者详细多了,单继承方式《JavaScript高级程序设计》中就讲了5种。

什么是面向对象(OOP)

  在作者看来,狭义的面向对象是一种编程方式,采用了抽象、封装、继承、多态这些设计方法,把难以读懂的代码抽象成一个个对象,增强代码的可读性、可靠性、可拓展性,是人们对编程经验的总结。

  推及到广义上,面向对象已经越了程序设计和软件开发作者认为面向对象又是一种思维方式,不局限于编程语言,甚至不局限编程本身,它把复杂的需求、业务逻辑抽丝剥茧、逐个分析。

  这一系列的文章作者会尝试用一些面向对象的思想去写,是不是很酷?

为什么要用面向对象这种编程方式?

  最初没有面向对象这个概念的时候,人们是按照计算机思维去写代码的(又叫面向过程,汇编和C一般是用这种方式),但是人理解计算机思维是比较困难的,代码量越多后期就越难维护,于是人们发明了面向对象这种编程方式,所以衍生出了许多面向对象的高级语言C++C#java等等,我们前端工程师使用的JavaScript也是其中的一种。

面向对象有以下这些好处:

  1、可读性强。如果你使用面向过程的方式编程,你可能过两三个月就忘了你的代码表达的意思,更别说让其他人理解你的代码。面向对象可以让你的代码遵循一定的规范,不论是你自己还是团队其他人理解起你的代码来更容易,非常方便多人协同开发。

  2、可扩展性强。面向对象强调代码的封装性,降低代码模块间的耦合度,这大大增强了代码的灵活性、可扩展性。

  3、复用代码。面向对象可把业务逻辑抽象拆分成一个个对象,比如猫和狗都可以把尾巴抽象成一个对象,猫和狗就都可以用尾巴这个对象。

  4、易维护。由于程序被抽象成一个个对象,那么即时是改变需求,只需要修改对应的对象就可以了,所以维护起来非常方便。

如果你编程有一段时间了,那你一定听说过大名鼎鼎的“设计模式”,面向对象就是设计模式的基础(可以理解为“前置技能”)。

在前端领域什么时候适合用面向对象?

  说实话前端领域使用面向对象编程的人不多,主要原因是因为很多WEB程序比较简单,用面向过程的编程方式足够满足需求,人们只是用JavaScript写写网页特效,提交个表单什么的。但随着互联网的发展,各种基于WEB的复杂需求不断出现,WEB程序越来越复杂,一个SPAsingle page web application单页Web应用)可能有几十万甚至上百万行代码,需要多人来开发、维护。

当你有以下这些感受的时候,这说明你应该学习面向对象了。

  1、项目的代码越来越多,感觉越来越难以维护;

  2、项目中好多需求很类似,一些代码主体上感觉差不多;

  3、需要和别人协同开发,别人有可能会改你的代码,你也可能改别人的代码,并且感觉沟通的很麻烦;

  4、两个月没看的代码就感觉不是自己写的了;

  5、程序经常出bug,并需要花很长时间去找原因;

  6、产品经理说“这个需求得改一下”的时候,内心一万个草泥马跑过;

  7、技术增长陷入了瓶颈。

  我相信javac++等语言的初学者学习面向对象肯定没有JavaScript这么难,因为这些面向对象语言已经将面向对象融入了语法,语法强制你去按照面向对象的方式编程,即使你不知道为什么这样做。

  JavaScript是通过模拟来实现面向对象的,这是很让人诟病的地方,理解困难,写起来比较麻烦,代码不干净。

  当然,并不是说JavaScript不如这些语言,JavaScript的灵活性是这些语言无法比拟的,这就让它有更多的可能,可以模拟很多编程语言的特性,JavaScript成为使用比例最高的编程语言是有理由的。

  而且并不是所有需求都必须用面向对象去解决,很多需求(特别是WEB程序)直接用面向过程去解决或许更方便,更快捷。

  先介绍一下这三个概念:

  是2015年制定的ECMAScript语言规范,在ES5的基础上扩充了新的语法特性,代表着JavaScript的未来,但还没有被大部分浏览器兼容,可以用babel等工具转化为ES5

  TypeScriptES5ES6的基础上又增加了类型检测等新特性,跟java很像,同时又保留了JavaScript的灵活性,非常适合大型应用程序。TypeScript不是ES5ES6这种官方产物,不被浏览器支持,需要用官方的工具转化为ES5ES6。因为angular2是用TypeScript写的,这让TypeScript最近大火,作者也是因为要用angular2做项目接触的TypeScript(偷偷告诉大家:TypeScript写起代码来非常爽)。

  从ES5ES6TypeScript,面向对象的味道越来越浓。ES5里面向对象靠模拟;ES6已经有class这个概念了,但还不够完善;TypeScript更是将面向对象推向了极致,这方面已经不比java差了。所以作者把这三者放在一起来对比、印证。

  新手可以只看ES5部分,学习有余力的和老鸟们可以把三部分demo一起看。

  这一系列后面的文章(抽象、封装、继承、多态、综合),作者尽量一周写一篇,各位看官如果觉得文章还行,不妨收藏起来,等作者更新了就可以第一时间阅读。

  如果大家觉得有什么需要补充、修改的,欢迎私信或留言。

  本章默认大家已经看过作者的前一篇文章

  封装(Encapsulation)就是把对象的内部属性和方法隐藏起来,外部代码访问该对象只能通过特定的接口访问,这也是面向接口编程思想的一部分。

  封装是面向对象编程里非常重要的一部分,让我们来看看没有封装的代码是什么样的:

  看似没有什么问题,但如果breed属性名修改了怎么办?比如换成this.type = ‘贵宾’,那所有使用Dog类的代码都要改变。

  如果类的代码和使用类的代码都是你写的,并且使用这个类的地方不多,你这么写无所谓。

  但如果使用这个类的地方比较多,或者协同开发时其它人还要使用你的类,那这样做就会让代码很难维护,正确的做法是:

  getBreed()就是接口,如果内部的属性变化了,比如breed换成了type ,那只需要改变getBreed()里的代码就可以了,并且你可以监听到所有获取这个属性的操作。

  所以封装有很多好处:

  1、只要接口不改变,内部的实现可以任意改变;

  2、使用者使用起来很方便,不用关系内部是如何实现;

  3、降低代码之间的耦合;

  4、满足大型应用程序和多人协同开发;

  其实还有另一种封装属性的方法,那就是用getter/setter,如下demo,本章不讲原理,只讲使用,原理可自行查资料:

13 如果不设置setter的话默认这个属性是不可设置的 14 但有点让人诟病的是,浏览器并不会报错 15 所以即使你想让breed是只读的,你也应该设置一个setter让其抛出错误:

  但这种方法写起来比较繁琐,作者一般是用getBreed()这种方法,getter/setter一般用在readonly的属性和一些比较重要的接口,以及重构没有封装接口的属性操作。

  还可以用闭包封装私有属性,是最安全的,但会产生额外的内存开销,所以作者不是很喜欢用,大家可自行了解。

  前两小节我们简单的了解了下封装,但这些肯定是不够用的,下面的我们先来了解下几个概念:

  私有属性:即只能在类的内部调获取、修改的属性,不允许外部访问。

  私有方法:仅供类内部调用的方法,禁止外部调用。

  公有属性:可供类外部获取、修改的属性。理论上讲类的所有属性都应该是私有属性,只能通过封装的接口访问,但一些比较小的类,或者使用次数比较少的类,你觉得比较方便的话也可以不封装接口。

  公有方法:可供外部调用的方法,实现接口的方法如getBreed()就是公有方法,以及对外暴露的行为方法。

  静态属性、静态方法:类本身的属性和方法。这个就没必要区分公有私有了,所有的静态属性、静态方法都必须是私有的,一定要通过封装接口访问,这也是上一章中作者为什么要用getInstanceNumber()来访问Dog.instanceNumber属性。

5 /*私有属性,人们共同约定私有属性、私有方法前面加上_以便区分*/ 8 /*属性的初始化最好放一个私有方法里,构造函数最好只用来声明类的属性和调用方法*/ 13 /*私有方法,只能类的内部调用*/ 19 /*公有方法:获取属性的接口方法*/ 24 /*公有方法:设置属性的接口方法*/ 28 /*这是一个小技巧,可以链式调用方法,只要公有方法没有返回值都建议返回this*/ 30 /*公有方法:对外暴露的行为方法*/ 35 /*公有方法:对外暴露的静态属性获取方法*/ 48 '这是本狗最幸福的时候'
15 /*其实就是通过getter实现的,只是ES6写起来更简洁*/ 20 /*跟ES5一样,如果不设置的话默认breed无法被修改,而且不会报错*/

  ES5ES6中虽然我们把私有属性和方法用“_”放在名字前面以区分,但外部还是可以访问到属性和方法的。

  TypeScrpt中就比较规范了,可以声明私有属性,私有方法,并且外部是无法访问私有属性、私有方法的:

  1、暴露给别人的类,多个类组合成一个类时,所有属性一定都要封装起来;

  2、如果你来不及封装属性,可以后期用getter/setter弥补;

  3、每个公有方法,最好注释一下含义;

  4、在重要的类前面最好用注释描述所有的公有方法;

  如果你喜欢作者的文章,记得收藏,你的点赞是对作者最大的鼓励;

  作者会尽量每周更新一章,下一章是讲继承;

  大家有什么疑问可以留言或私信作者,作者尽量第一时间回复大家;

  如果老司机们觉得那里可以有不恰当的,或可以表达的更好的,欢迎指出来,我会尽快修正、完善。

(1)安装ts本地编译器

这个编译器的作用是将typescript 代码转成JavaScript代码。因为ES6规范是在2015年后发布的,而现在大部分用户的浏览器支持ES5规范,所以需要将typescript代码转换成JavaScript代码才可以在用户的浏览器中运行

(2)方法类型,不需要任何返回值void

(5)可选参数,参数后加?

反过来,ES6支持,ts暂不支持

函数新特性之generator函数:控制函数的执行过程,手工暂停和恢复代码执行
声明方法,在function后面另*号,

①通过表达式将对象或数组拆解成任意数量的变量

变量名要一样,如果非要用别的名称可以使用:{code:codex,price}取别名的方式
如果对象中的属性又是一个对象,例如:

这时候,{code,price}中,price取到的就是一个对象,包含price1:200,price2:400,如果非要取其中的一个值的话,可以再使用一个析构表达式:{code,price:{price2}}就可以以取出price2的值了。如果getStock中还有其他属性,是不影响这个取值的。

②从数组中取值到本地变量

//多行表达式,效果和以上写法等同 //消除传统匿名函数的this指针问题例子

参数化的类型,一般用来限制集合的内容

接口:用来建立某种代码约定,使得其它开发者在调用某个方法或创建新的类时必须遵循接口所定义的代码约定。


 
(4)模块
模块可以帮助开发者将代码分割为可重用的单元。开发者可以自己决定模块中哪些资源(类、方法、变量)暴露出去供外部使用,哪些资源只在模块内使用。ts里一个文件就是一个模块。
export : 导出,对外暴露
import : 导入,引入外部资源


 
(5)注解annotation
注解为程序的元素(类,方法、变量)加上更直观明了的说明,这些说明信息与程序的业务逻辑无关,而是供指定的工具或框架使用的。这一块并没有太理解,先留白


(6)类型定义文件(*.d.ts)
类型定义文件用来帮助开发者在TypeScript中使用已有的JavaScript的工具包


①类型定义文件是为了能在TS上使用JS代码库、框架而引入的以.d.ts结尾的文件。


②类型定义文件是别人配好的:
比如使用jq :


③可以使用专门用来安装类型定义文件的工具:

我要回帖

更多关于 typescript和es6区别 的文章

 

随机推荐