JavaScript
JavaScript简介
JavaScript 是 Web 的编程语言,所有现代的 HTML 页面都可以使用 JavaScript,JavaScript 简单易学,且应用很广。
用法
HTML 中的 Javascript 脚本代码必须位于 <script>
与 </script>
标签之间。
Javascript 脚本代码可被放置在 HTML 页面的 <body>
和 <head>
<script>
标签
如需在 HTML 页面中插入 JavaScript,请使用 <script>
标签。
<script>
和 </script>
会告诉 JavaScript 在何处开始和结束。
<script>
和 </script>
之间的代码行包含了 JavaScript:
<script>
alert("我的第一个 JavaScript");
</script>
函数和事件
JavaScript 语句,会在页面加载时执行。
通常,我们需要在某个事件发生时执行代码,比如当用户点击按钮时。
如果我们把 JavaScript 代码放入函数中,就可以在事件发生时调用该函数。
基本语法
- 大小写敏感
- 标识符
- 所谓标识符,就是指变量、函数、属性的名字,或者函数的参数。标识符可以是按照下列格式规则组合起来的一或多个字符: 第一个字符只能是字母、下划线( _ )或美元符号( $ )之一; 其他字符可以是字母、下划线、美元符号或数字。 按照惯例,ECMAScript(European Computer Manufacturers Association) 标识符采用 驼峰大小写格式,也就是第一个字母小写,剩下的每个单词的首字母大写,如getNameById
语句后的分号建议添加,但不必须。 - ECMAScript 的变量是松散类型的,所谓松散类型就是可以用来保存任何类型(如: String、Number、Boolean以及Object等)的数据。换句话说,每个变量仅仅是一个用于保存值的占位符而已。 定义变量时要使用 var 操作符,后跟变量名(即一个标识符),如下所示: var message; 这行代码定义了一个名为 message 的变量,该变量可以用来保存任何值。
操作符
- 一元操作符( ++、 --)
- 布尔操作符(&&、||、!)
- 除下列值为假外其余皆为真: false、null、undefined、‘’、0、NaN
- 算术操作符(+ - * / %)
- 关系操作符(<> 、<=、>= 、、= != 、!==)
- 注意: ===称为全等(值和类型)。
- 条件操作符
var num1 = 11;
var num2 = 22;
var max = (num1 > num2) ? num1 : num2;
console.log(max);
- 语句
if do-while while for for-in for-of break continue switch等
var colors = ['red', 'green', 'blue', 'brown']; //colors是一个数组
//传统遍历
for(var i=0;i<colors.length;i++){
console.log(colors[i]);
}
//for-in,专注下标
for(var c in colors){
console.log(colors[c]);
}
//for-of,专注元素
for(var c of colors){
console.log(c);
}
//高级遍历
colors.forEach(c => console.log(c));
var other = colors.map(c => c + 'X');//map不仅遍历,还返回另一个数组
console.log(other);
- 函数
函数( function)对任何语言来说都是一个核心的概念。通过函数可以封装任意多条语句,而且可以在任何地方、任何时候调用执行。以下是一个函数示例:
function sayHi(name, message) {
console.log('Hello ' + name + ',' + message);
}
sayHi('YHD', '你好。');
- 对象
对象 Object 是ECMAScript 中使用最多的一个类型。我们常将数据和方法封装在对象中。
//方式一new
var person1 = new Object();//生成空对象
person1.name = 'Elon Musk';//设置对象的属性
person1.age = 46;
person1.job = 'SpaceX Rocket';
person1.sayName = function () { //设置对象的方法/函数,注意此处
console.log(this.name);
};
//方式二字面量
var person2 = {
name: 'Lary Page',
age: 47,
job: 'Software Engineer',
sayName: function () { //注意此处
console.log(this.name);
}
};
console.log(person1.job);
person1.sayName();
console.log(person2.job);
person2.sayName();
- 数组
数组的第一个位置来保存字符串,用第二位置来保存数值,用第三个位置来保存对象,以此类推。
创建方法:
//方式一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);
- 闭包
可以理解成一个函数内的内部函数,它被创建在一个函数内部,引用这其外部函数的变量值。
var a = function(){
varx = 1;
return function(y){
console.log(x+=y);//外部函数的x值就被包裹在引用对象中
}
}
var b = a();//实际上是返回function(y){...}的引用
b();//执行上面的引用,此时的x值变成了private的属性
- 数组方法
join():用指定的分隔符将数组每一项拼接为字符串
push():向数组的末尾添加新元素
pop():删除数组的最后一项
unshift():向数组首位添加新元素
shift():删除数组的第一项
slice():按照条件查找出其中的部分元素
splice():对数组进行增删改
filter():过滤功能
concat():用于连接两个或多个数组
indexOf():检测当前值在数组中第一次出现的位置索引
lastIndexOf():检测当前值在数组中最后一次出现的位置索引
every():判断数组中每一项都是否满足条件
some():判断数组中是否存在满足条件的项
includes():判断一个数组是否包含一个指定的值
sort():对数组的元素进行排序
reverse():对数组进行倒序
forEach():es5及以下循环遍历数组每一项
map():es6循环遍历数组每一项
find():返回匹配的项
findIndex():返回匹配位置的索引
reduce():从数组的第一项开始遍历到最后一项,返回一个最终的值
reduceRight():从数组的最后一项开始遍历到第一项,返回一个最终的值
toLocaleString()、toString():将数组转换为字符串
entries()、keys()、values():遍历数组
TypeScript
简介
TypeScript是JavaScript类型的超集(当前我们处于ES5),它可以编译成纯JavaScript。
TypeScript给JavaScript加上可选的类型系统,给JavaScript加上静态类型后,就能将调试从运行期提前到编码期,诸如类型检查、越界检查这样的功能才能真正发挥作用。 TypeScript的开发体验远远超过以往纯JavaScript的开发体验,无需运行程序即可修复潜在bug。
TypeScript支持未来的ES6甚至ES7。在TypeScript中,可以直接使用ES6的最新特性,在编译时它会自动编译到ES3或ES5。
TypeScript可以构建大型程序,并在任何浏览器、任何计算机和任何操作系统上运行,且是开源的。
数据类型
布尔类型(boolean)
数字类型(number)
字符串类型(string)
数组类型(array)
元组类型(tuple)
枚举类型(enum)
任意类型(any)
null 和 undefined(是never 数据类型的子类型)
void 类型
never 类型:
a. 表示的是那些永不存在的值的类型,never类型是任何类型的子类型,也可以赋值给任何类型;然而,没有类型是never的子类型或可以赋值给never 类型(除了never本身之外)。 即使 any也不可以赋值给never。
b. 是其他类型(包括 null 和 undefined)的子类型,代表从不会出现的值。
c. 返回never的函数必须存在无法达到的终点
函数
函数声明:
function run():string{
return 'run'
}
匿名函数法:
let fun2=function():number{
return 2;
}
alert(fun2());
let getInfo1=function (name:string,age:number):string {
return `${name}--${age}`
}
alert(getInfo1('zhangdan',3434))
没有返回值
function getInfo3(name:string,age:number):void {
console.log(`${name}--${age}`)
}
getInfo3('lixiaolong',3434)
函数重载:
function getInfo6(names:string):string;
function getInfo6(age:number):string;
function getInfo6(str:any):any{
if (typeof str==='string') {
return names
}else{
return str
}
};
alert(getInfo6(20))
箭头函数:
setTimeout(() => {
alert(3333)
}, 1000);
类
// 通过class创建类
class Animal {
// 类的属性
name: string;
// 类的构造器
constructor(name: string) {
this.name = name;
}
// 类的方法
sayHello():void{
alert("hello animal:"+this.name);
}
}
// 实例化类
var tom = new Animal("tom");
tom.sayHello();
类的继承
// 通过class创建类
class Animal {
// 类的属性
name: string;
// 类的构造器
constructor(name: string) {
this.name = name;
}
// 类的方法
sayHello(): void {
alert("hello animal:" + this.name);
}
}
// 继承Animal
class Cat extends Animal {
// 重写方法
sayHello(): void {
alert("hello cat:" + this.name);
}
}
class Dog extends Animal {
sayHello(): void {
alert("hello dog:" + this.name);
}
}
修饰符
class Animal {
private name: string; // 这里把name修饰符改为private
constructor(name: string) {
this.name = name;
}
sayHello(): void {
alert("hello animal:" + this.name);
}
}
class Cat extends Animal {
sayHello(): void {
alert("hello cat:" + this.name); //这里会报错,因为无法引用父类private修饰的属性
}
}
class Dog extends Animal {
sayHello(): void {
alert("hello dog:" + this.name); //这里会报错,因为无法引用父类private修饰的属性
}
}
Get/Set访问器
class Animal {
private name: string;
get name(): string { //通过get和set解决子类不能引用父类private修饰的属性的问题
return this.name;
}
set name(name: string) {
this.name = name;
}
constructor(name: string) {
this.name = name;
}
sayHello(): void {
alert("hello animal:" + this.name);
}
}
class Cat extends Animal {
sayHello(): void {
alert("hello cat:" + this.name);
}
}
class Dog extends Animal {
sayHello(): void {
alert("hello dog:" + this.name);
}
}
静态属性
class Table {
static width: Number = 100;
static height: Number = 50
}
var width: Number = Table.width;
继承
可以通过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();
模块Module
对于大型的项目,我们需要使用模块进行管理。每个 .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);