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

定义静态属性

  1. In other languages such as C#, Java, or even C, C++, you’d refer to these kinds of variables as static members.
  2. However, global variables are now generally considered bad practice and to be avoided at all costs.
  3. 所以在ES5里只能这样写:
function TodoService() {}TodoService.lastId = 0;TodoService.getNextId = function () {return (TodoService.lastId += 1);
};TodoService.prototype.add = function (todo) {var newId = TodoService.getNextId();
};
  1. 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相关推荐

  1. TypeScript Essential Notes 2 - ES6 Language Features

    syntactic suguar 语法糖 Default parameters Template strings use backtick symbol backtick 反引号 bracket 大括 ...

  2. 从JavaScript到TypeScript,Pt。 IIB:使用类,接口和混合器进行设计

    Class-based design has become such an instinct that many developers can't imagine any alternative. 基 ...

  3. TypeScript Decorators 的使用说明

    TypeScript Decorators 随着 TypeScript 和 ES6 中 Classes 的引入,现在存在一些需要额外功能来支持注释或修改类和类成员的场景. 装饰器提供了一种为类声明和成 ...

  4. 使用Python发送和读取Lotus Notes邮件

    转载自 https://blog.csdn.net/u013271714/article/details/78364932 转载自: Blog:Why So Serious  Github: LeoL ...

  5. ProGuard Usage 翻译

    Usage  用法 To run ProGuard, just type: 运行ProGuard,只需输入: java -jar proguard.jar options ... You can fi ...

  6. All About Angular 2.0

    2019独角兽企业重金招聘Python工程师标准>>> angular All About Angular 2.0 Posted by Rob Eisenberg on  Novem ...

  7. move std 函数 示例_确保(值类型)可拷贝类有默认构造函数

    C.43: Ensure that a copyable (value type) class has a default constructor C.43:确保(值类型)可拷贝类有默认构造函数 Re ...

  8. 测试中文编码_如何通过带回家的编码测试

    测试中文编码 A coding test is a crucial part of the interview process for a Software Developer role. A tak ...

  9. 注解@Qualifier的使用

    近期在整理一些spring的知识点,遇到关于@Qualifier这个注解的使用,记录一下. 先说这个注解的作用,和autowired对比: @Autowired默认是根据类型进行注入的,因此如果有多个 ...

最新文章

  1. [每天一道A+B]签到检测程序
  2. windows下git bash中文乱码解决办法
  3. Hadoop在运行几个T数据量时报堆内存溢出
  4. Linux基金会宣布成立Ceph基金会
  5. 126.单词接龙II
  6. python 获取foobar2000官网全部插件
  7. 模拟多线程给多用户发送短信
  8. 用C#实现汉字转化为拼音
  9. 南阳OJ 题目97 兄弟郊游问题
  10. centos7文件同步服务器,教你在 Centos7 中使用 Unison 同步文件
  11. ftp服务器项目,ftp服务器项目手册.doc
  12. 公众号开发精品教程(4)——生成带参数的二维码及合成海报
  13. 基于单片机1KW高频感应加热器控制系统仿真设计(毕设)
  14. 杰里之开立体声左右声道数据对调---【篇】
  15. 官网下载Eclipse(包含历史版本及该版本的子版本)
  16. 开视界 创未来丨酷雷曼第十期合作商交流会圆满举办
  17. CentOS 7 ping不通提示“Name or service not kown“的解决办法
  18. [RK3399/RK3328][Android10.0] storage:u盘/移动硬盘 每次开机都提示需要格式化
  19. Xilinx 7系列FPGA之Kintex-7产品简介
  20. HTML制作简单网页(京东新闻资讯页,歌曲推荐网页)

热门文章

  1. 贵金属买卖有运气吗?
  2. 什么是背景颜色和背景图片?!
  3. PTP授时服务器(NTP网络时间服务器)技术方案应用
  4. 2022年自考专业考试(英语)英语词汇学练习题
  5. Linux系统主机名、静态IP等配置
  6. RecBole小白入门系列博客(二) ——General类模型运行流程
  7. CAD中图纸比较功能怎么用
  8. oracle 选时间到五月,oracle日期时间函数小结
  9. python process参数_将参数传递给Scrapy python中的process.crawl
  10. 亚马逊云科技re:Inforce全球安全大会引领云上安全新风向