真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

【typescript】寫給JS老鳥的TS速成教程

寫給JS老鳥的TS速成教程

成都創(chuàng)新互聯(lián)于2013年成立,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項目成都做網(wǎng)站、成都網(wǎng)站建設(shè)網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元古浪做網(wǎng)站,已為上家服務(wù),為古浪各地企業(yè)和個人服務(wù),聯(lián)系電話:18980820575

搭建基礎(chǔ)開發(fā)環(huán)境

要準備的環(huán)境

node.js 14.14以上 ,vs code最新,vs code TS開發(fā)插件

開始開發(fā)

方式一:TS原生編譯開發(fā)

補充知識:i是install的簡寫,-g是global的簡寫,除此外還有-D = --save-dev 、-S= --save,現(xiàn)在新版npm cli好像會默認執(zhí)行—save

npm i -g typescript && tsc -init

vs code創(chuàng)建 文件夾/index.ts,

手動編譯 tsc+文件名,改一次編譯一次

自動編譯 Ctrl+shift+B —> 監(jiān)視模式,文件變動時自動編譯 或 如下:

① tsc 文件名 -w,缺點是只能監(jiān)視一個文件,除非開多個命令行。

② 創(chuàng)建tsconfig.json,只寫一對{},使其符合json規(guī)范,然后直接執(zhí)行 tsc,即可監(jiān)視所有ts文件的改動。

運行結(jié)果:創(chuàng)建index.html, script.import 編譯好的index.js,用瀏覽器打開index.html

開箱即用見 附件【TS_ori】

編譯控制

tsconfig.json是ts編譯器的配置文件,可以對編譯進行自定義

不知道可選值可以先給一個錯誤的值,編譯器會列出所有可選的正確配置值

tsconfig.json可以寫注釋,因為其是ts編譯器的配置文件。

{

// 初步

"include":[ //指定哪些目錄的ts文件需要被編譯,包含目錄

"./src/**/*" //.當(dāng)前目錄 src文件夾 **任意目錄 *任意文件

],

"exclude":[],//指定哪些ts文件不被編譯,排除目錄,有默認值,比如node_modules

"extends":"./config/base",//繼承某個配置文件,配置復(fù)用

"files":[],//指定ts文件編譯,包含文件,與include類似

//進階

"compilerOptions":{

"target":"ES6", //指定ts編譯成何種js版本,即目標代碼的版本

//ES2015(ES6),ES2016...ESNext(最新版ES)

"module":"ES6",//指定模塊化解決方案

"lib":["dom"],//用來指定項目中使用到的庫,一般不寫此屬性(有默認值),除非代碼在nodejs中運行,缺少某些庫,如dom。dom庫為document

"outDir":"./dist",//指定編譯后文件所在目錄。dist即distribution,發(fā)行版

"outFile":"./dis/app.js",//將代碼合并為一個文件,若需要把各模塊合并為一個文件,只能支持amd and system模塊方案

"allowJs":false, //是否對js進行編譯,默認否 - false //合并文件一般不用outFile,而是結(jié)合打包工具來實現(xiàn)

"checkJs":false, //是否檢查js代碼是否符合語法規(guī)范

"removeCommentss":true,//是否移除注釋

"noEmit":false,//執(zhí)行編譯但是不生成編譯后的文件,場景是只用到ts編碼和類型檢查, 不須編譯

"noEmitOnError":false,//發(fā)送錯誤時不生成編后的譯文件,默認為false,為的是讓js程序員緩慢過渡到ts,建議改為true

"strict":false,//以下三個檢查的總開關(guān),建議開發(fā)時設(shè)為true

"alwaysStrict":false,//指定編譯后的js文件是否使用嚴格模式。嚴格模式:語法嚴格,在browser性能好一些

"noImplicitAny":false,//Implicit隱式的,開啟隱式any的檢查,不允許使用

"noImplicitThis":false,//不允許不明確類型的this

"strictNullChecks":false,//嚴格檢查空值,若一個變量可能為null,則報錯,除非先進行非空判斷或box?.addEventListener()

}

}

方式二:自動化開發(fā)

補充知識:webpack-cli是通過命令行來使用webpack、ts-loader是webpack加載器,是ts和webpack的橋梁

補充知識:webpack這東西就是會沿著你給定的一個入口文件去遍歷所有關(guān)聯(lián)的文件,然后按照一定規(guī)則重新整理、壓縮成新的一批文件,我們的文件格式是無窮無盡的,webpack不可能認識和處理全部格式,所以我們通過加入各種loader,稱加載器,來幫助webpack認識它們。

創(chuàng)建空文件夾,執(zhí)行npm init -y(完成項目初始化)

npm i -D webpack webpack-cli typescript ts-loader

撰寫webpack配置。要注意的是,webpack打包必須配合tsconfig.json使用,也就是你的ts代碼處要有這個tsconfig.json文件,因為ts程序的具體編譯的工作還是由ts本身提供,而ts編譯本身要用到tsconfig.json,現(xiàn)在看來,ts-loader真的僅僅是個橋梁。

在package.json中加入打包命令build:webpack,執(zhí)行npm run build。

撰寫配置

使用chrome來查看ts程序的運行結(jié)果

補充知識:webpack可以支持自動生成html文件并引入打包好的資源,以演示代碼效果,這比自己手動寫個html方便多了,生成這個html文件有兩種方式,配置式,如傳個title參數(shù),其他由webpack自己決定,或者自己擬定一個html模板交給插件。

cnpm i -D html-webpack-plugin

自動化構(gòu)建--所寫即所見

cnpm i -D webpack-dev-server ,package.json 加入 "start":"webpack serve --open" ,npm run start

清楚舊的打包文件

打包默認模式是用新文件覆蓋舊文件,可能存在殘留問題,解決方法:clean-webpack-plugin

指定可引入的文件

指定哪些文件可以被其他文件作為模塊來引入,這里的引入是代碼文件之間的引入,這樣我們就可以愉快地使用ESM(ES Module)了

解決目標代碼的兼容性問題

補充知識:前端常見兼容性問題有兩種,一種是瀏覽器內(nèi)核類,一種是規(guī)范版本類。前者主要表現(xiàn)為在Chrome能運行的代碼,在Firefox卻出現(xiàn)問題,在iPhone默認瀏覽器能運行的代碼在華為默認瀏覽器卻有問題;后者主要表現(xiàn)為ES6的代碼在瀏覽器中報錯,因為ES6對比ES5變化是較大的,現(xiàn)在ES規(guī)范每年一個版本,瀏覽器跟進也比以前快了,這個問題正變得越來越不是問題。

TS的tsc僅僅能夠?qū)崿F(xiàn)把ts源碼編譯成不同ES規(guī)范版本的js代碼而已。

babel/core是babel的核心庫、present-env是預(yù)置環(huán)境,預(yù)置不同瀏覽器環(huán)境,幫助代碼兼容不同瀏覽器,babel-loader是結(jié)合webpack和babel的橋梁、core-js(Modular standard library)可以使老版本的瀏覽器使用到新版本的js的一些技術(shù),如promises等,由于這個庫比較龐大,內(nèi)含很多小庫,且是模塊化的,我們應(yīng)按需使用,按需使用我們直接通過webpack來實現(xiàn)

webpack rules的use執(zhí)行順序是從下往上執(zhí)行,我們先用ts-loader把ts轉(zhuǎn)換為js,然后用babel-loader把新版本的js轉(zhuǎn)換為老版本/兼容性高的js

  1. cnpm i -D @babel/core @babel/preset-env babel-loader core-js

關(guān)于兼容性打包后仍報錯

補充知識:設(shè)置了targets.ie==11后,打包的代碼拿到ie11運行依然報錯,原因在于webpack打包后的代碼用了一個箭頭函數(shù)實現(xiàn)的自執(zhí)行函數(shù)包裹,作用是創(chuàng)造一個代碼作用域,防止全局變量污染等,它實際是webpack自動生成的,與babel無關(guān),babel只能源文件內(nèi)的箭頭函數(shù)起作用,實際上,這可能是webpack故意為之,其本身就是不想兼容某些低版本瀏覽器,解決方法,out加上environment:{arrowFunction:false},取消箭頭函數(shù)。

TS語言

報錯信息,assign:賦值、指派、指定,resolve:解析、決定、解決

默認ts代碼有錯誤,仍然可以編譯生成js,在tsconfig中可更改

ts可編譯成任意版本js

若賦初值,ts會根據(jù)值類型推算變量類型,這會使變量聲明加上類型變得多此一舉,沒錯,實際上,類型檢測更多是用給函數(shù)傳參(形參)和返回值的。

類型

補充知識:可用字面量代替類型名,如10,以后只能賦值10,有點常量的意思。除此之外,還有聯(lián)合類型、任意類型等

talk is cheap,show me the code

export const zex: number = 1;

{

let a: number = 10;

let b: number = 20;

console.log(a, b)

//計算變量類型

let c = true;

//計算函數(shù)返回值類型

function sum(a: number, b: number): string {

return a + b + "";

}

let result = sum(a, b);

}

const zex:number=1;

{

// 字面量賦值

let a:10;

let a1:number;

let b:10=10;

a=10;

a1=10;

// 用 或符號 構(gòu)成 聯(lián)合類型

let c:"male"|"female";

c="male";

c="female";

let d:string|number;

d=10;

d="hello";

// 任意類型 - 關(guān)閉類型檢測

let e:any;

e=10;

e="female";

e=true;

// 隱式any

let f;

f=10;

f="female";

f=true;

// 賦值

// 以下不報錯,這導(dǎo)致a的類型檢測失效

a1=e;

// unknown同any差不多,但是可解決以上問題,是一個類型安全的any

let g:unknown;

// a=g;報錯,應(yīng)改為

if(typeof g == "number"){

a1=g;

}

//斷言:判斷的語言,根據(jù)實際情況,把某個變量人為(自己)地斷定為某種類型,跳過編譯

a1 = g as number;

a1 = g;

//函數(shù)的返回值

//返回值為number|string型

function sum(a:number,b:number){

if(a>b){

return a+b;

}else{

return a+b+"";

}

}

function sum2(a:number,b:number):number|string{

if(a>b){

return a+b;

}else{

return a+b+"";

}

}

// 空返回

function sum3(a:number,b:number):void{

return;

}

function sum4(a:number,b:number):void{}

function sum5(a:number,b:number):void{

return undefined;

}

// never:永遠不會返回結(jié)果

// 沒有返回值也是一種返回值,而never是空空

// 在程序報錯時,代碼立即停止執(zhí)行,程序結(jié)束,函數(shù)結(jié)束,所以永遠不會有值返回,事情不會發(fā)生

function err():never{

throw new Error("err");

}

}

{

// object其實是無用的,因為ts一且皆對象,并沒有起到類型限制的作用

let a:object;

a={};

a=function(){};

//以下有效

let b:{name:string};

b={name:"John"};

// b={name:"John",age:12}結(jié)構(gòu)不一致報錯

// ?-可選屬性

let c:{name:string,age?:number};

c={name:"John",age:12};

c={name:"John"}

// 任意屬性:自由添加屬性,新屬性未知

// 新屬性名為字符串,屬性值為任意類型,propName命名隨意

let d:{name:string,[propName:string]:any}

d={name:"John",str:123}

let d1:{name:string,[propName:string|number]:any}

d1={name:"John",str:123}

d1={name:"John",123:123}

// 限制函數(shù),單Function無意義

let e:(a:number,b:number)=>number

// 數(shù)組

let f:string[];

f=["John"]

let f1:Array;

f1=[123];

// 元組:固定長度的數(shù)組

let g:[String,String];

// 必須符合給定,不多不少

g=["Hello","Hello"];

//考慮數(shù)據(jù)存儲與表示分離,數(shù)據(jù)庫存儲應(yīng)簡短、非字符串,此時Object并不滿足要求

// 枚舉,默認從0開始

enum Gender{

male=0,

female=1

};

let h:{name:string,gender:Gender};

h={name:"Jhon",gender:Gender.female};

console.log(h.gender,h.gender==Gender.female)

// & - 與,類型組合

let i:number&string //無意義

let i1:{name:string}&{age:number};

i1={name:"John",age:18};

// 類型的復(fù)用-別名

let j1:number;

let j2:1|2|3|4|5;

let j3:1|2|3|4|5|6;

type myType=number;

type myType2=1|2|3|4|5;

let k1:myType;

let k2:myType2;

let k3:myType2|6;

k3=3

k3=6

// k3=7 報錯

}

// 類

class Person {

// 實例屬性,通過實例訪問

readonly name: string = "默認名字";

age: number = 18;

// 類屬性,通過類訪問

static avgAge: number = 18;

//只讀屬性

static readonly baseName: string = "張"

// 類方法

sayHello(name: string): string {

return "Hello";

}

static sayHi(name: string): string {

return "Hi";

}

};

const per = new Person();

Person.avgAge = 19;

per.age = 20;

// Person.name="三三"; // 報錯

// Person.baseName="李"; // 報錯

console.log(Person.avgAge, per.age);



// 構(gòu)造器與this

class Dog {

name: string;

age: number;

constructor(name: string, age: number) {

// this表示當(dāng)前實例

this.name = name;

this.age = age;

}

bark() {

// 當(dāng)前調(diào)用方法的對象,如dog1.bark(),this為dog1

console.log(this, "旺旺旺");

}

}

const dog: Dog = new Dog("旺財", 3);

// 繼承

{

class Animal {

name: string;

age: number;

constructor(name: string, age: number) {

this.name = name;

this.age = age;

}

bark() {

}

}

class Dog extends Animal {

bark() {

console.log(this.name + this.age + "旺旺旺");

}

run() {

console.log("蹦蹦跳跳");

}

}

class Cat extends Animal {

sex: string;

constructor(name: string, age: number, sex: string) {

// 調(diào)用父類構(gòu)造器

super(name, age);

this.sex = sex;

}

bark() {

// 引用父類的方法

super.bark();

}

}

const cat = new Cat("小喵", 3, "母");

//抽象類

//對于某些類,由于本身拿來實例化是不合適的,且我們也不希望被這樣做

//因此我們就把他設(shè)為抽象類,只可以繼承,不可以實例化

abstract class Food {

name: string;

color: string;

// 抽象類須有構(gòu)造器

constructor(name: string, color: string) {

this.name = name;

this.color = color;

}

abstract eat(name: string): void;

abstract cook(name: string): number | string;

}

/**

* 在限制對象的類型上,以下兩種方式功能一致

* 接口,定義了類的結(jié)構(gòu)(屬性、方法)

* 此接口非彼接口,它與Java的接口有點不同

*/

type myType = {

name: string,

age: number

};

interface myInterface {

name: string;

age: number;

}

// 接口可以重復(fù)定義,實際效果是同名接口的總和

interface myInterface {

sex: string;

}

const man: myInterface = {

name: "張三",

age: 18,

sex: "男"

}

// 限制類的結(jié)構(gòu)

interface myInterface2 {

name: string;

sayHi(): void;

}

interface myInterface3 { }

class People implements myInterface2, myInterface3 {

name: string;

constructor(name: string) {

this.name = name;

}

sayHi(): void {

console.log(this.name);

}

}

/**

* 抽象類和接口

* 抽象類:

* 1、可以普通方法,也可以抽象方法

* 2、通過繼承來使用,TS 類的設(shè)計為單繼承

*

* 接口:

* 1、只有抽象方法

* 2、通過實現(xiàn)來使用,支持多繼承

*/

}

// 屬性的封裝 - 保護類的屬性

// 屬性可被隨意修改將導(dǎo)致對象中的數(shù)據(jù)變得不安全

// 通過類修飾符解決這個問題

// 默認為public,屬性可被隨意修改

{

class Person {

name: string;

public sex: string;

public age: number;

constructor(name: string, sex: string, age: number) {

this.name = name;

this.sex = sex;

this.age = age;

}

}

// 最強安全性

// private修飾的屬性,只有兩種修改方式:

// 1、構(gòu)造器傳入

// 2、調(diào)用實例方法修改,這種方法在java中被稱為setter

// 此外,這種方式也給屬性的訪問帶來麻煩,我們同樣只能通過方法return該屬性來訪問,在java中稱為getter

// 這種setter和getter模式在C#中被吸收為語法:

/**

* get{

return _name;

}

set{

_name = value;

}

*/

class Person2 {

private name: string;

private sex: string;

private age: number;

protected height: number;

constructor(name: string, sex: string, age: number, height: number) {

this.name = name;

this.sex = sex;

this.age = age;

this.height = height;

}

setName(name: string): void {

this.name = name;

}

getName(): string {

return this.name;

}

}

// 此外,private屬性也不可以被子類訪問,protected可以

class Person3 extends Person2 {

showName(): void {

// 無法訪問name,可以訪問height

// console.log(this.name);

console.log(this.height);

}

}

// 泛型

// 當(dāng)一種類型是什么要在實際中才能確定是,我們使用泛型

// 泛型就是類型的抽象表示(代表)

// 當(dāng)以下函數(shù)的參數(shù)與返回值類型一致,但是無法確定是什么具體類型時,用泛型

function fn(a: number): number {

return a;

}

// 能否使用any?不行,一是關(guān)掉了類型檢查,這將埋下隱患,二是無法體現(xiàn)兩者類型一致

function fn2(a: T): T {

return a;

}

function fn3(a: T, b: K, c: I): T {

return a;

}

function fn4(a: T, b: K, c: number): number {

return c;

}

// 在調(diào)用含泛型函數(shù)時,一般會自動推定泛型的類型,我們也可手動指定

fn2(1);

fn4(1, "2", 3);

fn4(1, "2", 3);

}

【附件】

https://github.com/heytheww/TSLenrning


網(wǎng)頁題目:【typescript】寫給JS老鳥的TS速成教程
文章源于:http://weahome.cn/article/dsojhij.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部