目录
1 JavaScript & TypeScript介绍
1.1 什么是JavaScript?
1.2 什么是TypeScript?
1.3 JavaScript与TypeScript的主要区别
2 JavaScript学习总结
2.1 语法
2.2 变量
2.3 函数
2.4 对象
对象Object
2.5 数组
2.6 闭包
3 TypeScript学习总结
3.1 类
3.2 模块化module
JavaScript是互联网上最流行的脚本语言,这门语言可用于 HTML和 web,更可广泛用于服务器、PC、笔记本电脑、平板电脑和智能手机等设备,JavaScript是一种轻量级的编程语言。
虽然它是作为开发Web页面的脚本语言而出名,但是它也被用到了很多非浏览器环境中,JavaScript 基于原型编程、多范式的动态脚本语言,并且支持面向对象、命令式、声明式、函数式编程范式。
TypeScript (TS) 是一个 JavaScript 超集,其目标与 JavaScript 相同。
TypeScript 是一种开源编程语言,具有许多特性,如继承、类、可见性范围、命名空间、接口、合并和其他现代特性以及静态和动态类型。它支持注释、变量、函数、语句、模块和表达式。
作为一种强类型的编程语言,TypeScript调试(在编译过程中)更容易,所以更适用于复杂应用。
JavaScript | TypeScript |
---|---|
支持动态网页内容 | 为帮助项目解决代码复杂性而创建的JavaScript超集 |
解释性语言,因此只有在运行时才会发现错误 | 在编译期间可以检测和修复错误 |
弱类型,无法选择静态类型 | 强类型,支持静态和动态类型 |
可以直接在浏览器中使用 | 将代码转换为 JS 以实现浏览器兼容性 |
不支持模块、泛型和接口 | 支持模块、泛型和接口 |
不支持可选参数 | 可选参数可以添加到函数中 |
使用数字和字符串作为接口 | 数字和字符串是对象 |
大量社区支持,包括大量文档 | 社区支持正在增长,不像以前那么强大 |
不支持原型设计 | 原型设计是一个可行的选择 |
不需要事先的脚本知识 | 学习和编码需要时间,需要脚本知识 |
无需设置构建环境 | 对于静态类型定义,需要适当地构建设置(npm 包) |
JavaScript是弱类型编程语言,定义变量都使用 var 定义,与 Java 这种强类型语言有区别。在定义后可以通过 typeOf() 来获取JavaScript中变量的数据类型.
TypeScript 中语法和JavaScript中的语法相差不大
变量的作用是给某一个值或对象标注名称。比如我们的程序中有一个值123,这个值我们是需要反复使用的,这个时候 我们最好将123这个值赋值给一个变量,然后通过变量去使用123这个值。
变量的声明: 使用var关键字声明一个变量
函数是由一连串的子程序(语句的集合)所组成的,可以被外部程序调用,向函数传递参数之后,函数可以返回一定的值。
通常情况下,JavaScript代码是自上而下执行的,不过函数体内部的代码则不是这样。如果只是对函数进行了声明,其中的代码并不会执行,只有在调用函数时才会执行函数体内部的代码。
这里要注意的是JavaScript中的函数也是一个对象,使用typeof检查一个函数对象时,会返回function。
通常使用函数声明来创建一个函数
function 函数名([形参1,形参2,...,形参N]) {
语句...
}
使用函数表达式来创建一个函数
语法格式:
var 函数名 = function([形参1,形参2,...,形参N]) {
语句....
}
函数参数
JS中的所有的参数传递都是按值传递的,也就是说把函数外部的值赋值给函数内部的参数,就和把值从一个变量赋值给另一个变量是一样的,在调用函数时,可以在()中指定实参(实际参数),实参将会赋值给函数中对应的形参
调用函数时,解析器不会检查实参的类型,所以要注意,是否有可能会接收到非法的参数,如果有可能,则需要对参数进行类型的检查,函数的实参可以是任意的数据类型
调用函数时,解析器也不会检查实参的数量,多余实参不会被赋值,如果实参的数量少于形参的数量,则没有对应实参的形参将是undefined
对象 Object
是ECMAScript 中使用最多的一个类型。我们常将数据和方法封装在对象中。
创建对象有如下两种方式,我们常用第二种。
//方式一new
var person = new Object();//生成空对象
person.name = 'Elon Musk';//设置对象的属性
person.age = 46;
person.job = 'SpaceX Rocket';
person.sayName = function(){ //设置对象的方法/函数,注意此处
console.log(this.name);
};
//方式二字面量
var person = {
name: 'Lary Page',
age: 47,
job: 'Software Engineer',
sayName: function(){ //注意此处
console.log(this.name);
}
};
console.log(person.job);
person.sayName();
虽然 Object
构造函数或对象字面量都可以用来创建单个对象,但这些方式有个明显的缺点:使用同一个接口创建很多对象,会产生大量的重复代码。为解决这个问题,人们开始使用工厂模式的一种变体。代码如下:
function createPerson(name, age, job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
console.log(this.name);
};
return o;
}
var person1 = createPerson('Steve Jobs',56 , 'Inventor');
var person2 = createPerson('Linus Torvalds', 49, 'Software Engineer');
var person2 = createPerson('Julian Assange', 47, 'Ethical Hacker');
数组也是对象的一种,数组是一种用于表达有顺序关系的值的集合的语言结构,也就是同类数据元素的有序集合。
数组的存储性能比普通对象要好,在JavaScript中是支持数组可以是不同的元素,这跟JavaScript的弱类型有关,但大多数时候都是相同类型元素的集合。数组内的各个值被称作元素,每一个元素都可以通过索引(下标)来快速读取,索引是从零开始的整数。
创建数组有以下两种方法,我们常用第二种。
//方式一new
var colors = new Array('red', 'blue', 'green');
//方式二字面量
var colors = ['red', 'blue', 'green']; // 创建一个包含 3 个字符串的数组
console.log(colors[1]);
colors[3] = 'brown';
console.log(colors.length);
var names = []; // 创建一个空数组
var hyBird = [1, 2, 'haha', {firstName: 'Yong', lastName: 'Wang'}]; //不推荐!
console.log(hyBird[3].firstName);
闭包是Closure,这是静态语言所不具有的一个新特性。
闭包就是函数的局部变量集合,只是这些局部变量在函数返回后会继续存在。
闭包就是就是函数的“堆栈”在函数返回后并不释放,我们也可以理解为这些函数堆栈并不在栈上分配而是在堆上分配
当在一个函数内定义另外一个函数就会产生闭包。
类是属性(有些什么)和函数(能干什么)的集合,是生成对象(Object)或类实例的模板。使用类描述所创建的对象共同的属性和方法,支持面向对象的所有特性,比如 类、接口等。
类的定义和使用
//类的定义和使用
class MyInfo { //class是关键字,类名默认全部大写首字母
name: string; //属性
weather: string; //属性
constructor(name: string, weather: string){ //构造函数,一般用于初始化。如果没有,TS会自动生成一个,以备用new创建类实例时调用。
this.name = name;
this.weather = weather;
}
printInfo(): void { //其它函数,无返回值
console.log(`Hello, ${this.name}.`);
console.log(`Today is ${this.weather}.`);
}
}
let myData = new MyInfo('QiGe', 'raining'); //使用new关键字生成对象,即该类的实例
myData.printInfo();
类的属性和函数的访问权限
类中的属性和函数都有访问权限,默认为public即全局可访问,其次为protected即可在类的内部和其子类的内部可访问,最后为private,只能在该类内部可访问。
//访问权限
class MyInfo { //class是关键字,类名默认全部大写首字母
public name: string; //public属性,可省略
private _weather: string; //私有属性,习惯以_开头进行命名
constructor(name: string, weather: string){ //构造函数,一般用于初始化
this.name = name;
this._weather = weather;
}
printInfo(): void { //其它函数
this._test();
console.log(`Hello, ${this.name}.`);
console.log(`Today is ${this._weather}.`);
}
private _test(): void {
console.log('You can not call me outside!');
}
}
let myData = new MyInfo('QiGe', 'raining'); //使用new关键字生成对象
console.log(myData._weather); //error!
myData._test(); //error
myData.printInfo();
继承
可以通过extends关键字继承其它类,从而成为其子类
class Animal {
// 当构造函数传入的参数加上了“访问权限控制符”,则同时会声明同名类属性,并赋值
constructor(public name: string) { }
protected log(message: string) {
console.log(message);
}
move(distanceInMeters: number = 0) {
this.log(`${this.name} moved ${distanceInMeters}m.`);//请注意name来自何处
this.log('==============');
}
}
class Horse extends Animal {
constructor(name: string) {
super(name); // 通过super调用父类构造器
}
run(distanceInMeters = 50) { //自己独有的函数
this.log("Clop, clop...");
super.move(distanceInMeters); // 通过super调用父类方法
}
}
class Eagle extends Animal {
constructor(name: string) { super(name); }
reborn() { //自己独有的函数
console.log('Reborn? It is a joke, hahaha!');
}
}
let tom: Horse = new Horse("Tommy the Palomino");
tom.run(8964);
let sam: Eagle = new Eagle("Sammy the Hawk");
sam.move(1024);//sam的move函数来自何处?
sam.reborn();
对于大型的项目,我们需要使用模块进行管理。每个 .ts 文件就是一个模块,通过 export 来对外部模块暴露元素,通过 import 来引入模块。
在项目文件夹下新建目录modules和文件main.ts,并在modules下新建name.ts和weather.ts文件,如下:
//modules/name.ts
export class Name { //用export对外部暴露该类
constructor(private first: string, private second: string) {}
get nameMessage() {
return `Hello ${this.first} ${this.second}`;
}
}
//modules/weather.ts
export class WeatherLocation { //用export对外部暴露该类
constructor(private weather: string, private city:string) {}
get weatherMessage() {
return `It is ${this.weather} in ${this.city}`;
}
}
//main.ts
//用import从外部模块文件导入,默认后缀.ts去掉
import { Name } from "./modules/name";
import { WeatherLocation } from "./modules/weather";
let name = new Name('Wang', 'Yong');
let loc = new WeatherLocation('raining', 'ChongQing');
console.log(name.nameMessage);
console.log(loc.weatherMessage);