More on Design Patterns
npm install nodemon concurrently
nodemon: rerun node at any time our files changed
concurrently:run multiple typescripts at the same time
package.json
"scripts": {
"start:build": "tst -w",
"start:run": "nodemon build/index.js",
"start": "concurrently npm:start:*"
},
tsconfig.json配置rootDir和outDir
一般是
"outDir": "./build", /* Redirect output structure to the directory. */
"rootDir": "./src",
- Js小客堂--确定type
1.Narrow type of a value to a primative type
typeof
=>number/string/boolean/symbol
2.Narrow down every other type of value
instanceof
=>Every other value that is created with a constructor function - Js小客堂--写class内置方法加get的区别
加上get,那么引用这个方法的时候就不需要加括号
get length(): number {
return this.data.length
}
object.length
//没有get
//object.length()
- Abstract Classes
- only used as parent class
-
can contain real impletation for some methods
sorter.ts
import { NumbersCollection } from './NumbersCollection';
interface Sortable{
length: number;
compare(leftIndex: number, rightIndex: number): boolean;
swap(leftIndex: number, rightIndex: number): void;
}
export abstract class Sorter {
abstract compare(leftIndex:number,rightIndex:number):boolean; //abstract class=>will implement by who extends it(child class)
abstract swap(leftIndex:number,rightIndex:number):void;
abstract length:number;
sort(): void {
const { length } = this;
for (let i = 0; i < length; i++) {
for (let j = 0; j < length - 1 - i; j++) {
if (this.compare(j, j + 1)) {
this.swap(j, j + 1);
}
}
}
}
}
LinkedList.ts
import { Sorter } from './Sorter';
class Node {
next: Node | null = null;
constructor(public data: number) {}
}
export class LinkedList extends Sorter {
head: Node | null = null;
add(data: number): void {
const node = new Node(data);
if (!this.head) {
this.head = node;
return;
}
let tail = this.head;
while (tail.next) {
tail = tail.next;
}
tail.next = node;
}
get length(): number {
if (!this.head) {
return 0;
}
let length = 1;
let node = this.head;
while (node.next) {
length++;
node = node.next;
}
return length;
}
at(index: number): Node {
if (!this.head) {
throw new Error('Index out of bounds');
}
let counter = 0;
let node: Node | null = this.head;
while (node) {
if (counter === index) {
return node;
}
counter++;
node = node.next;
}
throw new Error('Index out of bounds');
}
compare(leftIndex: number, rightIndex: number): boolean {
if (!this.head) {
throw new Error('List is empty');
}
return this.at(leftIndex).data > this.at(rightIndex).data;
}
swap(leftIndex: number, rightIndex: number): void {
const leftNode = this.at(leftIndex);
const rightNode = this.at(rightIndex);
const leftHand = leftNode.data;
leftNode.data = rightNode.data;
rightNode.data = leftHand;
}
print(): void {
if (!this.head) {
return;
}
let node: Node | null = this.head;
while (node) {
console.log(node.data);
node = node.next;
}
}
}
NumbersCollection.ts
import { Sorter } from './Sorter';
export class NumbersCollection extends Sorter {
constructor(public data: number[]) {
super();
}
sort(){
}
get length(): number {
//get !
return this.data.length;
}
compare(leftIndex: number, rightIndex: number): boolean {
return this.data[leftIndex] > this.data[rightIndex];
}
swap(leftIndex: number, rightIndex: number): void {
const leftHand = this.data[leftIndex];
this.data[leftIndex] = this.data[rightIndex];
this.data[rightIndex] = leftHand;
}
}
CharacterCollection.ts
import { Sorter } from './Sorter';
export class CharacterCollection extends Sorter {
constructor(public data: string) {
super();
}
get length(): number {
return this.data.length;
}
compare(leftIndex: number, rightIndex: number): boolean {
return (
this.data[leftIndex].toLowerCase() > this.data[rightIndex].toLowerCase()
);
}
swap(leftIndex: number, rightIndex: number): void {
const characters = this.data.split('');
const leftHand = characters[leftIndex];
characters[leftIndex] = characters[rightIndex];
characters[rightIndex] = leftHand;
this.data = characters.join(' ');
}
}
index.ts
import { Sorter } from './Sorter';
export class CharacterCollection extends Sorter {
constructor(public data: string) {
super();
}
get length(): number {
return this.data.length;
}
compare(leftIndex: number, rightIndex: number): boolean {
return (
this.data[leftIndex].toLowerCase() > this.data[rightIndex].toLowerCase()
);
}
swap(leftIndex: number, rightIndex: number): void {
const characters = this.data.split('');
const leftHand = characters[leftIndex];
characters[leftIndex] = characters[rightIndex];
characters[rightIndex] = leftHand;
this.data = characters.join(' ');
}
}