-
学习Angular2的过程中,很多特性都依靠装饰器来实现,当你看到装饰器这个概念的时候,可能会把其跟设计模式里的Decorator搞混,其实这是完全不同的两个东西。 什么是装饰器? 虽然很像,他们要干的事都很相似——都是想要对一个已有的模块做一些“修饰工作”,所谓修饰工作就是想给现有的模块加上一些小装饰(一些小功能,这些小功能可能好多模块都会用到),但又不让这个小装饰(小功能)侵入到原有的模块中的代码里去。但是OO的Decorator简直就是一场恶梦,不信你可以看看维基上的词条Decorator pattarn里的UML图和那些代码,不烧死一堆脑细胞才怪。 目前为止Javascript中的装饰器还处于建议征集的第二阶段,在不远的ES7中大家能有幸体验一把了。Angular2最初是使用Google自己搞的AtScript语言编写的(牛逼哄哄的感觉,我要写框架了,先搞出来一种语言吧……),但是在 NG-Conf 2015 上,Angular 团队宣布与 TypeScript 团队进行合作(原因不详),但TypeScript需要引入一个类Annotation 特性的语法(及其扩展),此外为了能更好地支持 Angular,TypeScript 引入的装饰器特性并不是纯粹的装饰器提案,附加了一部分特性: [*]支持通过 emitDecoratorMetadata 选项暴露类构造函数的参数类型; [*]支持针对类构造器/方法参数的装饰器; [*]支持类成员属性的装饰器。 就这样Angular与Typescript拥抱在一起了。 装饰器的分类 根据被装饰的对象,我们可以将TS中的装饰器分为以下四种: [*]类装饰器 (Class decorators) [*]属性装饰器 (Property decorators) [*]方法装饰器 (Method decorators) [*]参数装饰器 (Parameter decorators) 类装饰器 类装饰器在类声明之前被声明(紧靠着类声明)。类装饰器应用于类构造函数,可以用来监视,修改或替换类定义。类装饰器不能用在声明文件中( .d.ts),也不能用在任何外部上下文中(比如declare的类)。 类装饰器表达式会在运行时当作函数被调用,类的构造函数作为其唯一的参数。 我们来看一个例子: 可以看到,通过类装饰器我们可以对类的原型对象做一定的修改(装饰)。 编译后的源码为:"use strict";var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators) r = (c 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r;};function sealed(constructor) { Object.seal(constructor); Object.seal(constructor.prototype);}var MyClass = (function () { function MyClass() { this.a = 0; this.b = "hello"; } MyClass = __decorate([ sealed ], MyClass); return MyClass;}());var obj = new MyClass();// obj.c = true; // 编译报错 属性装饰器 属性装饰器声明在一个属性声明之前(紧靠着属性声明)。属性装饰器不能用在声明文件中(.d.ts),或者任何外部上下文(比如 declare的类)里。 属性装饰器表达式会在运行时当作函数被调用,传入下列2个参数: 1. 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。 2. 成员的名字。 示例如下: 输出如下: 可以看到,属性装饰器返回的函数会在解释类的对应属性时被调用一次,并可以得到装饰器的参数和被装饰的属性的相关信息。 装饰器方法的调用只会在加载代码时执行一次,调用被装饰的属性不会触发装饰器方法。 方法装饰器 方法装饰器声明在一个方法的声明之前(紧靠着方法声明)。它会被应用到方法的属性描述符上,可以用来监视,修改或者替换方法定义。方法装饰器不能用在声明文件( .d.ts),重载或者任何外部上下文(比如declare的类)中。 方法装饰器表达式会在运行时当作函数被调用,传入下列3个参数: 1. 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。 2. 成员的名字。 3. 成员的属性描述符。 示例如下: 输出如下:false, undefined, [object Object], func, {"writable":true,"enumerable":true,"configurable":true}true, this is static, function MyClass() { }, sFunc, {"writable":true,"enumerable":true,"configurable":true}call static methodcall static methodcall methodcall method 可以看到,方法装饰器返回的函数会在解释类的对应方法时被调用一次,并可以得到装饰器的参数和被装饰的方法的相关信息。 装饰器方法的调用只会在加载代码时执行一次,调用被装饰的方法不会触发装饰器方法。 参数装饰器 参数装饰器声明在一个参数声明之前(紧靠着参数声明)。参数装饰器应用于类构造函数或方法声明。参数装饰器不能用在声明文件(.d.ts),重载或其它外部上下文(比如 declare的类)里。 参数装饰器表达式会在运行时当作函数被调用,传入下列3个参数: 1. 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。 2. 成员的名字。 3. 参数在函数参数列表中的索引。 示例如下: 输出结果为:1 [object Object], func, 22 [object Object], func, 13 [object Object], func, 04 call method5 call method 可以看到,参数装饰器返回的函数会在解释方法的参数时被调用一次,并可以得到参数的相关信息。我们有3个参数就调用了3次。 装饰器方法的调用只会在加载代码时执行一次,调用被装饰的参数的方法不会触发装饰器方法。 Angular中的装饰器 理解了Typescript中的装饰器,我们回头再看Angular中的装饰器就不会感觉到鸭梨了,Angular中内置的装饰器如下: [*]类装饰器:@Component、@NgModule、@Pipe、@Injectable [*]属性装饰器:@Input、@Output、@ContentChild、@ContentChildren、@ViewChild、@ViewChildren [*]方法装饰器:@HostListener [*]参数装饰器:@Inject、@Optional、@Self、@SkipSelf、@Host 这些后续慢慢挖吧。 — END — 别忘了给 作者: 刘赵强 点赞呦! 有什么想对作者说的吗?快来留言吧!长按二维码关注“THINK”
-
TypeScript 是由微软开发的编程语言,是 JavaScript 的超集,自12年首个公开版本发布后,发展迅速,特别是近几年,随着 VSCode(TypeScript 推荐 IDE)的诞生及前端框架巨头 Angular2.0 版本敲定选用 TypeScript 作为基础语言后,更是一路狂奔,较新的 Google 趋势报告、StackOverflow 开发者调研等业界权威排行显示,TypeScript 热度超过了 ES6。 那么 TypeScript 究竟为何物,为开发者提供了哪些便利,本文将围绕其重要特性展开介绍,希望对你有所帮助。 与 JavaScript 的关系 TypeScript 是 JavaScript 类型的超集 [*]它可通过编译成纯 JavaScript 在浏览器端运行 [*]它完全支持 JavaScript 语法,并向其语言添加了可选的静态类型和基于类的面向对象编程等特性 ES6 提供了哪些重要特性 说到 TypeScript,就不得不提 ES6,ES6 是 JavaScript 语言的下一代标准,已在15年正式发布。 TypeScript 最初就是基于 ES6 开发的,因此,在介绍 TypeScript 特性之前,我们先介绍一下 ES6 提供了哪些重要特性,我们在这里介绍的 ES6 特性 TypeScript 是完全支持的。 [*]模块 ES6 引入了模块特性,这为前端开发带来了很大的便利:1)简化代码:不需要引入 requireJS/seaJS 等第三方模块管理器进行模块处理了,只需使用 import 与 export 即可进行模块管理; 2)提升效率:浏览器原生模块与 HTTP2 的结合,速度将变得非常快,是一种更优的按需加载形式。 [*]类 类是面向对象语言的基础,它提供的三个重要特性:封装性、继承性、多样性,提升了代码可维护性和可复用性,为开发者带来了福音。虽然 ES6 提供的类功能并不完备,但是对于 JavaScript 语言本身来说,已是一个很大的进步。 [*]变量定义 ES5 被吐槽较多的是其混乱的变量定义机制,这个问题为开发者带来困扰,如:循环变量泄露为全局变量、变量提升、变量重复声明。而 ES6 在兼容老式变量定义的前提下,提供了 let 和 const 关键字,在变量定义方面华丽转身。 [*]箭头函数 箭头函数存在的意义在于:1)简化代码:让开发者简便的使用符号 “=>” 代替 function 定义函数,同时也提供了其它语法简化函数的定义,比如简单函数不用写 return 等; 2)拯救 this:我们知道 ES5 函数中的 this 取决于调用对象,在业务关系不明确情况下,很容易出现问题,而箭头函数默认能保存函数创建时的 this 值(继承于父级作用域),解决了 ES5 this 指向可变性带来的问题(当然,ES6 也提供了 API 支持 this 对象的定义)。 这部分可能不是很好理解,代码举例说明一下:如下所示:在 deck 对象中定义 createCardPicker 函数,该函数在后续业务代码中调用,如果使用 function 方式定义函数,则 this 的指向是被调用对象,即 window 对象,最终代码执行报错;而箭头函数指向一直为 deck 对象,不会存在该问题,代码段如下: [*]字符串模板 ES6 支持字符串格式(如换行符、空格)保持、字符串插值功能,功能支持后,开发再也不用维护一大堆可读性很差的拼接字符串了。 TypeScript 带来了哪些特性 虽然随着 ES6 的发布,JavaScript 已经发展的非常强悍了,但是,依然有很多企业选择使用 TypeScript,这是为什么呢?接下来,让我们看看哪些酷炫特性让 TypeScript 如此具有吸引力。 [*]强类型 JavaScript 是弱类型语言,TypeScript 是 JavaScript 的超集,可以理解为是Type+JavaScript,即强类型的 JavaScript。那么,强类型为开发者带来了哪些好处呢? - 类型约束提升了代码可读性和可维护性; - 类型允许在开发时使用高效的开发工具和常用操作(比如静态检查和代码重构)。 [*]类的增强 ES6 提供的类特性功能并不完备,它只是基于原型继承的一部分扩展,使用上无法达到真正面向对象编程所带来的编程快感。而 TypeScript 做到了真正的面向对象。 [*]接口 接口特性用来约束一组对象或函数的类型,也是面向对象编程的一个重要概念,它确保了对象赋值或函数使用时,变量的形式及类型与接口形状保持一致。该特性的支持增强了语言的抽象性和编程的灵活性,同时也提升了代码可维护性。 [*]装饰器 装饰器是 Java、Python 等语言的一个重要特性,它可以让其它函数在不需要做任何代码变动的前提下增加额外功能,它适用于有切面需求的场景,如:**日志、权限校验等场景。 该特性的支持为我们提供了两方面好处: - 代码可复用性提升; - 为我们的接口定义提供了一种更优雅的选择方式,如 Angular2+ 中 @Component 等大量装饰器的使用。 [*]强大的工具支持 TypeScript 最大的卖点之一是它的附带工具所带来的开发体验。这些工具支撑了 TypeScript 强大的 IDE 智能提示、静态检查、重构功能,可以说是大型项目的标配。 写在最后 每个语言都有它的优缺点,TypeScript 也不例外: [*]工具编译带来的问题 需要编译为 JavaScript 后才能正常运行,编译后的代码质量取决于工具,虽然 Typescript 生成的代码质量已经很高,但它毕竟是工具编译的。 [*]学习成本 相比于 JavaScript,由于 TypeScript 强类型等特性的支持会带来附加的学习成本,因此团队在技术选型时需要衡量投资回报率。 然而,瑕不掩瑜,对大部分项目,尤其是大型项目或需要长期维护的项目,TypeScript 仍然是个很好的选择。TypeScript 把不错的静态语言(Java)的 95% 的有用场景带到了 JavaScript,为前端开发者带来了从未有过的编程体验,在代码质量、可读性和可维护性方面提升显著,而这些正是我们做项目时所期望的。 — END — 作者: 许晓燕 别忘了给作者点赞哟 有什么想对作者说的吗?快来留言吧!相关链接: [*]华为云APP动画《空城计外传》诞生,这些事你不可不知! [*]华为云的《速度与激情》! [*]2017年 Javascript 现状:React 称霸,GraphQL 要火! [*]如何用Axure做出“跳一跳”游戏 THINK体验设计 微信ID:hw-Think长按二维码关注有惊喜
-
本帖最后由 huopodeajuan 于 2017-12-31 21:14 编辑TypeScript是由微软Anders Hejlsberg(安德斯·海尔斯伯格,丹麦人,Borland Turbo Pascal编译器的主要作者。进入微软公司后,先后主持了Visual J++、.Net, C# 和 TypeScript。)领衔开发的一种开源编程语言。TypeScript没有抛弃JavaScript的语法另起炉灶,而是做成了JavaScript的超集,在其基础上添加了可选的静态类型和基于类的面向对象编程。TypeScript可以编译成纯JavaScript,支持所有的JavaScript语法。 8007 官网:http://www.typescriptlang.org/
-
TypeScript是由微软Anders Hejlsberg(安德斯·海尔斯伯格,丹麦人,Borland Turbo Pascal编译器的主要作者。进入微软公司后,先后主持了Visual J++、.Net, C# 和 TypeScript。)领衔开发的一种开源编程语言。TypeScript没有抛弃JavaScript的语法另起炉灶,而是做成了JavaScript的超集,在其基础上添加了可选的静态类型和基于类的面向对象编程。TypeScript可以编译成纯JavaScript,支持所有的JavaScript语法。 7923 官网:http://www.typescriptlang.org/
上滑加载中
推荐直播
-
全面解析华为云EI-API服务:理论基础与实践应用指南
2024/11/29 周五 18:20-20:20
Alex 华为云学堂技术讲师
本期直播给大家带来的是理论与实践结合的华为云EI-API的服务介绍。从“主要功能,应用场景,实践案例,调用流程”四个维度来深入解析“语音交互API,文字识别API,自然语言处理API,图像识别API及图像搜索API”五大场景下API服务,同时结合实验,来加深开发者对API服务理解。
回顾中 -
企业员工、应届毕业生、在读研究生共探项目实践
2024/12/02 周一 19:00-21:00
姚圣伟 在职软件工程师 昇腾社区优秀开发者 华为云云享专家 HCDG天津地区发起人
大神带你一键了解和掌握LeakyReLU自定义算子在ONNX网络中应用和优化技巧,在线分享如何入门,以及在工作中如何结合实际项目进行学习
即将直播 -
昇腾云服务ModelArts深度解析:理论基础与实践应用指南
2024/12/03 周二 14:30-16:30
Alex 华为云学堂技术讲师
如何快速创建和部署模型,管理全周期AI工作流呢?本期直播聚焦华为昇腾云服务ModelArts一站式AI开发平台功能介绍,同时结合基于ModelArts 的实践性实验,帮助开发者从理论到实验更好地理解和使用ModelArts。
去报名
热门标签