TypeScript Essential Notes 5 - Classes
Understanding prototypical inheritance
function TodoService(){this.todos =[];
}TodoService.prototype.getAll = function(){return this.todos;
}var service = new TodoService();
service.getAll();
this 关键字指的是对象的实例。所以第六行的 this.todos 会在运行时引用第二行的 this.todos
JavaScript 为对象分配原型的最常见方式是使用构造函数,它实际上只是一个使用 new 关键字调用的函数。当您使用 new 关键字初始化对象时,JavaScript 会做三件事。首先,它创建一个新对象。其次,它将新对象的原型设置为构造函数的原型。第三,它执行您使用 new 关键字调用的函数,在该方法中将新对象称为 this 。
Defining a class
// function TodoService() {// this.todos = [];
// }// TodoService.prototype.getAll = function () {// return this.todos;
// };// var service = new TodoService();
// service.getAll();//=====>
// class TodoService {// todos: Todo[] = [];// constructor(todos: Todo[]) {// this.todos = todos;
// }// getAll() {}
// }//=====>
class TodoService {constructor(private todos: Todo[]) {}getAll() {return this.todos;}
}interface Todo {name: string;state: TodoState;
}enum TodoState {New = 1,Active,Completed,Deleted,
}
Applying static properties
定义静态属性
- In other languages such as C#, Java, or even C, C++, you’d refer to these kinds of variables as static members.
- However, global variables are now generally considered bad practice and to be avoided at all costs.
- 所以在ES5里只能这样写:
function TodoService() {}TodoService.lastId = 0;TodoService.getNextId = function () {return (TodoService.lastId += 1);
};TodoService.prototype.add = function (todo) {var newId = TodoService.getNextId();
};
- in ES6:
class TodoService {static lastId: number = 0;//静态属性constructor(private todos: Todo[]) {}add(todo: Todo) {var newId = TodoService.getNextId();}getAll() {return this.todos;}//静态方法static getNextId() {return (TodoService.lastId += 1);}
}interface Todo {name: string;state: TodoState;
}enum TodoState {New = 1,Active,Completed,Deleted,
}
Making properties smarter with accessors
to define and substantiate证实 simply object
this code is actually perfectly legitimate合法
it must be preceded by the set keyword
let passcode = 123456;class Employee {private _fullName: string; //私有变量 an internal variableget changeName() {return this._fullName;}set changeName(newName) {if (passcode && passcode == 123456) {this._fullName = newName;} else {throw "error";}}
}
Inheriting behavior from a base class
derive from源自于 a class
extends BaseClass
class TodoStateChanger {constructor(private newState: TodoState) {}canChangeState(todo: Todo): boolean {return !!todo;}changeState(todo: Todo): Todo {if (this.canChangeState(todo)) {todo.state = this.newState;}return todo;}
}class CompleteTodoStateChanger extends TodoStateChanger {constructor() {super(TodoState.Completed); // 在派生类的构造函数中必须调用 super()}canChangeState(todo: Todo): boolean {return (super.canChangeState(todo) &&(todo.state == TodoState.Active || todo.state == TodoState.Deleted));}
}
Implementing an abstract class
enforce my intent 执行我的意图
nothing stopping some rogue javascripit code from creating a new instance
没有什么能阻止一些流氓 javascripit 代码创建一个新实例
is designed to guard against, there is ultimately nothing i can do about that
旨在防范,最终我无能为力
All I can do is focus on the protection that it gives me at development time and in that regard, abstract base classes are an excellent tool.
我所能做的就是专注于它在开发时给我的保护,在这方面,抽象基类是一个很好的工具。
abstract class TodoStateChanger {constructor(private newState: TodoState) {}// canChangeState(todo: Todo): boolean {// return !!todo;// }// =>改成抽象类abstract canChangeState(todo: Todo): boolean; // 必须在派生类中实现changeState(todo: Todo): Todo {if (this.canChangeState(todo)) {todo.state = this.newState;}return todo;}
}class CompleteTodoStateChanger extends TodoStateChanger {constructor() {super(TodoState.Completed); // 在派生类的构造函数中必须调用 super()}canChangeState(todo: Todo): boolean {return (//super.canChangeState(todo)//=>!!todo &&(todo.state == TodoState.Active || todo.state == TodoState.Deleted));}
}
Controlling visibility with access modifiers
使用访问修饰符控制可见性
abstract class TodoStateChanger {// 抽象类中把它从private改成protected,在派生类中可以被访问到constructor(protected newState: TodoState) {}
}class CompleteTodoStateChanger extends TodoStateChanger {constructor() {super(TodoState.Completed);var a = this.newState // 抽象类中把它从private改成protected,在派生类中可以被访问到}
}
class SmartTodo {// name: string;// constructor(name: string) {// this.name = name;// }// => 不用专门声明一个name,直接在构造函数里加任何修饰符public/protected/private作为声明constructor(public name: string) {this.name = name;}
}
私有变量加下划线
private static _lastId: number = 0;
Implementing interfaces
class TodoService implements IToDoService {private static _lastId: number = 0;get nextId() {return (TodoService._lastId += 1);}constructor(private todos: Todo[]) {}add(todo: Todo) {todo.id = this.nextId;this.todos.push(todo);return todo;}delete(todoId: number): void {var toDelete = this.getById(todoId);var deletedIndex = this.todos.indexOf(toDelete);this.todos.splice(deletedIndex, 1);}getAll(): Todo[] {// 不直接return Todo数组出去// 现在互联网传输的数据一般都是json格式// 将数据传出去之前,先用JSON.stringify把数据转成json字符串格式,方便传输// 否则得到的是[object object]// 接收到数据后,用JSON.parse把数据转成对象格式以便本地使用var clone = JSON.stringify(this.todos);return JSON.parse(clone);}getById(todoId: number): Todo {//JS's built-in array method filter JS的内置的数组过滤方法var filtered = this.todos.filter((i) => i.id == todoId); if (filtered.length) {return filtered[0];}return null;}
}interface IToDoService {add(todo: Todo): Todo;delete(todoId: number): void;getAll(): Todo[];getById(todoId: number): Todo;
}interface Todo {id: number;name: string;state: TodoState;
}enum TodoState {New = 1,Active,Completed,Deleted,
}
no, quite the contrary 不,恰恰相反
icing on the cake 锦上添花
TypeScript Essential Notes 5 - Classes相关推荐
- TypeScript Essential Notes 2 - ES6 Language Features
syntactic suguar 语法糖 Default parameters Template strings use backtick symbol backtick 反引号 bracket 大括 ...
- 从JavaScript到TypeScript,Pt。 IIB:使用类,接口和混合器进行设计
Class-based design has become such an instinct that many developers can't imagine any alternative. 基 ...
- TypeScript Decorators 的使用说明
TypeScript Decorators 随着 TypeScript 和 ES6 中 Classes 的引入,现在存在一些需要额外功能来支持注释或修改类和类成员的场景. 装饰器提供了一种为类声明和成 ...
- 使用Python发送和读取Lotus Notes邮件
转载自 https://blog.csdn.net/u013271714/article/details/78364932 转载自: Blog:Why So Serious Github: LeoL ...
- ProGuard Usage 翻译
Usage 用法 To run ProGuard, just type: 运行ProGuard,只需输入: java -jar proguard.jar options ... You can fi ...
- All About Angular 2.0
2019独角兽企业重金招聘Python工程师标准>>> angular All About Angular 2.0 Posted by Rob Eisenberg on Novem ...
- move std 函数 示例_确保(值类型)可拷贝类有默认构造函数
C.43: Ensure that a copyable (value type) class has a default constructor C.43:确保(值类型)可拷贝类有默认构造函数 Re ...
- 测试中文编码_如何通过带回家的编码测试
测试中文编码 A coding test is a crucial part of the interview process for a Software Developer role. A tak ...
- 注解@Qualifier的使用
近期在整理一些spring的知识点,遇到关于@Qualifier这个注解的使用,记录一下. 先说这个注解的作用,和autowired对比: @Autowired默认是根据类型进行注入的,因此如果有多个 ...
最新文章
- [每天一道A+B]签到检测程序
- windows下git bash中文乱码解决办法
- Hadoop在运行几个T数据量时报堆内存溢出
- Linux基金会宣布成立Ceph基金会
- 126.单词接龙II
- python 获取foobar2000官网全部插件
- 模拟多线程给多用户发送短信
- 用C#实现汉字转化为拼音
- 南阳OJ 题目97 兄弟郊游问题
- centos7文件同步服务器,教你在 Centos7 中使用 Unison 同步文件
- ftp服务器项目,ftp服务器项目手册.doc
- 公众号开发精品教程(4)——生成带参数的二维码及合成海报
- 基于单片机1KW高频感应加热器控制系统仿真设计(毕设)
- 杰里之开立体声左右声道数据对调---【篇】
- 官网下载Eclipse(包含历史版本及该版本的子版本)
- 开视界 创未来丨酷雷曼第十期合作商交流会圆满举办
- CentOS 7 ping不通提示“Name or service not kown“的解决办法
- [RK3399/RK3328][Android10.0] storage:u盘/移动硬盘 每次开机都提示需要格式化
- Xilinx 7系列FPGA之Kintex-7产品简介
- HTML制作简单网页(京东新闻资讯页,歌曲推荐网页)