Web技术基础——JavaScript&TypeScript

写在前面

JavaScript与TypeScript:JavaScript是Web的编程语言,它控制了网页的行为,相比于TS,它在用户编程时,不会进行报错提醒,只有在代码运行的时候才会报错,是一款极度“自由”的语言,在自由的同时也带来了许多不便之处。而TypeScript的出现改变了这一点,它是JavaScript类型的超集,可以编译成纯JavaScript,它提供报错提醒,便于用户在编写代码时,及时修改代码。

一、Javascript

1.简介

JavaScript 是互联网上最流行的脚本语言,这门语言可用于 HTML 和 web,更可广泛用于服务器、PC、笔记本电脑、平板电脑和智能手机等设备。

HTML 中的 Javascript 脚本代码必须位于 < script > 与 < /script > 标签之间。Javascript 脚本代码可被放置在 HTML 页面的 < body > 和 < head > 部分中。

  • 如图所示,这是我从该网页截取的部分代码
    在这里插入图片描述

2.变量

变量是用于存储信息的"容器"

在JS中,用“var”来定义一个变量,例如:

var x=1var y=2;
var z=x+y;

与代数一样,JavaScript 变量可用于存放值(比如 x=1)和表达式(比如 z=x+y)。
变量可以使用短名称(比如 x 和 y),也可以使用描述性更好的名称(比如 age, sum, totalvolume)。

  • 变量必须以字母开头
  • 变量也能以 $ 和 _ 符号开头
  • 变量名称对大小写敏感( U 和 u 是不同的变量)

数据类型

值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、空(Null)、未定义(Undefined)、Symbol。

引用数据类型(对象类型):对象(Object)、数组(Array)、函数(Function),还有两个特殊的对象:正则(RegExp)和日期(Date)。

JavaScript 变量能保存以上的几种数据类型,其中最为常见的是字符串(“starboy”)
当向变量分配文本类型时,应该用双引号或单引号包围这个值,如:

var word=“starboy”;

当向变量赋的值是数值时,若用引号包围数值,该值会被作为文本来处理,如:

var a=1”;
var b="2";
var c=a+b;
结果是:
c=12

3.操作符

操作符类型:一元操作符、布尔操作符、算术操作符、关系操作符、条件(问号)操作符、赋值操作符

  • 一元操作符: ++ –
  • 布尔操作符: && || !
除下列值为假外其余皆为真: falsenullundefined''0NaN
  • 算术操作符 + - * / %
  • 关系操作符 <> <=>= == === != !==
其中“ ===”称为全等,即值和类型都要相等
  • 条件(问号)操作符 ? :
能够有效简洁代码
  • 赋值操作符 = += -+ *= /= %=

4.语句

JavaScript 语句由以下构成: 值、运算符、表达式、关键词和注释。

其中关键词有

关键词含义
break终止 switch 或循环
continue跳出循环并在顶端开始
debugger停止执行 JavaScript,并调用调试函数(如果可用)
do … while执行语句块,并在条件为真时重复代码块
for标记需被执行的语句块,只要条件为真
function声明函数
if … else标记需被执行的语句块,根据某个条件
return退出函数
switch标记需被执行的语句块,根据不同的情况
try … catch对语句块实现错误处理

5.函数

函数( function)对任何语言来说都是一个核心的概念。通过函数可以封装任意多条语句,而且可以在任何地方、任何时候调用执行。

函数是包裹在花括号中的代码块,其前面使用了关键词 function

function [函数名]()
{
    [执行代码]
}

若在执行代码中需要调用参数,则在函数定义之初需要传递参数

function [函数名](变量1,变量2...,...,...)
{
    [执行代码]
}

若执行完成代码后,需要返回一个希望的值,则需要return

function [函数名](变量1,变量2...,...,...)
{
    [执行代码]
    return [变量]}

大小写敏感

在JS中,函数名对大小写特别敏感,如

function hanshu(变量1,变量2...,...,...)
{
    [执行代码]
    return [变量]}
function hanShu(变量1,变量2...,...,...)
{
    [执行代码]
    return [变量]}

可以代表不同的两个函数,但是在命名函数名时,通常采用第二种命名方式,驼峰方法,即除第一个单词外,其余单词首字母大写,如:
function deleteStringfunction showThisWord等。

闭包

闭包是Closure,这是静态语言所不具有的一个新特性。简而言之,闭包就是:函数的局部变量集合,只是这些局部变量在函数返回后会继续存在。

闭包就是就是函数的“堆栈”在函数返回后并不释放,可以理解为这些函数堆栈并不在栈上分配而是在堆上分配。
当我们在一个函数内定义另外一个函数就会产生闭包,它使得函数拥有私有变量变成可能,如:

function greeting(name) {
    var text = 'Hello ' + name; // local variable
    return function() { console.log(text); }//注意该函数无名称,称为匿名函数
}
var sayHello = greeting('Closure');
sayHello(); 

6.对象

对象 Object 是ECMAScript 中使用最多的一个类型。我们常将数据和方法封装在对象中,我个人觉得可以理解为C语言中的结构体

创建对象有两种方式
一是利用new构建一个空对象,然后再依次设置对象的属性,如:

var music = new Object();//生成空对象
music.name = 'Still young';//设置对象的属性
music.singer = 'Jason';
music.kind = 'passive';
music.player = function(){    //设置对象的方法
   
};

第二种方法是采用字面量的形式直接设置对象的属性,如:

var music = {
    name: 'Still young',
    singer: 'Jason',
    kind: 'passive';
    player: function(){       
         [执行代码]
    }
};

一般来说,我们更常用第二种方法。

虽然 Object 构造函数或对象字面量都可以用来创建单个对象,但这些方式有个明显的缺点:使用同一个接口创建很多对象,会产生大量的重复代码。为解决这个问题,人们开始使用工厂模式的一种变体。代码如下:

function music(name, singer, kind){
    var o = new Object();
    o.name = name;
    o.singer = singer;
    o.kind = kind;
    o.player = function(){
        [执行代码]
    };
    return o;
}
var music1 = music('Still young', "Jason" , 'passive');
var music2 = music('become old', "Jason" , 'sadness');
var music3 = music('keep young', "Jason" , 'meaningful');

7.数组

数组用于在单一变量中存储多个值。

创建数组同样有两种方式:

  • var [数组名] = [元素1, 元素2, …],如:
var supermarket_list=["fish","fruit","vagetable"] 
  • var [数组名] = new Array(元素1, 元素2, …);
var supermarket_list=new Array("fish",“fruit”,“vagetable”)

我们更常用第一种方法,因为第一种代码简洁、可读性强、执行速度更快。

8.链式语法

链式语法已变得非常流行。实际上这是一种非常容易实现的模式。

基本上,你只需要让每个函数返回,this代表包含该函数的对象,这样其他函数就可以立即被调用。如:

var bird = {
  catapult: function() {
    console.log( 'Yippeeeeee!' );
    return this;
  },
  destroy: function() {
    console.log( "That'll teach you... you dirty pig!" );
    return this;
  }
};
bird.catapult().destroy();

二、Typescript

1.变量

不同于JS(在JS中声明变量使用var),在TS中使用let或const申明变量,并加上类型说明,且作用域为块级即以{}为界
let表示变量,const类似常量
let (or const) [变量名]:[变量类型]

let item: string = 'TypeScript';
let item: number | string = 'TS';
item = 100;
let age: number = 89;
age = 64;

const pi: number = 3.14159;//pi以后不可改变,类似常量

解构

将对象、数组中的元素拆分到指定变量中,方便使用

  • 解构数组
let input = [89, 64, 2018, 10];
let [first, second] = input;//
console.log(first); // 89
console.log(second); // 64
let [one, ...others] = input; //剩余变量
console.log(...others);
//展开
let newArr = [89, ...others, 18];
console.log(newArr);
  • 解构成员
let o = {
  a: "foo",
  b: 12,
  c: "bar"
};
let {a, b} = o;//注意使用{},且变量名需与对象中道属性名一致
console.log(a, b);

2.函数

函数是包裹在花括号中的代码块,其前面使用了关键词 function

  • 无参函数:
function [函数名]:[类型]()
{
    [执行代码]
}
  • 带参函数:
function [函数名]:[类型]([参数1]:[类型],[参数2]:[类型],...)
{
    [执行代码]
}

例如:

function add(x: number, y: number): number {
  return x + y;
}
  • 匿名函数
let [变量名] = function([类型]([参数1]:[类型],[参数2]:[类型],...):[函数类型] { [执行代码] };

例如:

let myAdd = function(x: number, y: number): number { return x + y; };
  • 箭头函数
    特点:简化函数定义、解决this问题
    例如:
let greeting1 = () => `Hello TS!`;

let greeting2 = (name: string) => `Hello ${name}`;
console.log(greeting2('QiGe'));

let add1 = (n1: number, n2: number) => n1 + n2;
console.log(add1(1, 2));

let add2 = (n1: number, n2: number) => {
  let sum = n1 + n2;
  return sum;

3.类

类是属性和函数的集合,是生成对象或类实例的模板

类描述了所创建的对象共同的属性和方法。
TypeScript 支持面向对象的所有特性,比如 类、接口等。

  • 类的定义和使用
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();
  • 存取器
  • 若我们在类外部,要对类中的成员进行访问时,可以设置gettersetter操作其private属性,即使public属性也如此。
//getter和setter
class MyInfo { //class是关键字,类名默认全部大写首字母
  private readonly _name: string; //私有属性,外部不可访问。readonly使其只能在初始化时赋值,以后不可更改。    
  private _weather: string; //私有属性,习惯以_开头进行命名

  constructor(name: string, weather: string){ //构造函数,一般用于初始化
    this._name = name;
    this._weather = weather;
  }
  get name(): string {
    return this._name;
  }
  set name(value: string) {  //error! _name有readonly属性
    this._name = value;
  }
  get weather(): string {
    return this._weather;
  }
  set weather(value: string) {
    this._weather = value;
  } 
}
  
let myData = new MyInfo('QiGe', 'raining'); //使用new关键字生成对象
console.log(myData.name, myData.weather);
myData.weather = 'sunny'; //OK
myData.name = 'Wang'; //error!
console.log(myData);

注意:readonly关键字将属性设置为只读的,只读属性必须在声明时或构造函数里被初始化。只带有get不带有set的存取器自动被推断为readonly。

  • 静态属性
    当类中的属性或函数被定义为静态时,即:static,则可直接使用,可以直接通过类名调用。

//静态属性,内建或自定义,无需new即可使用
console.log(Math.round(89.64)); //90
console.log(Math.pow(2, 8)); //256
class MyStaticClass {
  static place = 'Earth';
  static printInfo() {
    console.log('We have only one Earth!');
  }
}
console.log(MyStaticClass.place);
MyStaticClass.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();
          

4.模块

对于大型的项目,我们需要使用模块进行管理。每个 .ts 文件就是一个模块,通过 export 来对外部模块暴露元素,通过 import
来引入模块。 模块是自声明的;两个模块之间的关系是通过在文件级别上使用imports和exports建立的。

采用以下语句建立模块:

export interface [模块名] { 
   // 代码部分
}

采用以下语句导入模块:

 import { [模块名] } from " [模块所在路径] ";
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值