基本语法
大小写敏感 以分号作为语句分隔符,单句一行可以省略 //单行注释;/* */多行注释
- 一些字面量:
Infinity
无穷大;NaN
非数值(类型还是数值);true/false
布尔型;' '/" "
字符串;${ }
格式化字符串,${}内是变量,输出时替代为对应变量的值;null
空;undefined
未定义 - 标识符:必须以字母、_或开头,可由字母、数字、_和组成
- 变量声明:
var
声明全局变量,let
声明局部变量,const
声明常量 变量在赋值时确定类型(数值,字符串,布尔型,对象(数组,函数,对象,类)),let a=[]
定义数组;let a={}
定义对象;let a=function(){}
定义函数;class a{}
定义类 - 解构赋值:用[ , ]=[ , ]的形式对其中元素进行同时赋值
- 算数操作符:+加 -减 *乘 /除 %模 **幂 ++自加 --自减,在右侧先赋值再运算,在左侧先运算后赋值 += -= *= /= %= 迭代运算
- 关系操作符:==等于;===值等于且类型等于;!=值不等于;!==值不等于或类型不等于;>大于;>=大于等于;<小于;<=小于等于
- 逻辑操作符:&&与 ||或 !非 返回布尔型
输入输出
输入
prompt:let 变量=prompt('提示信息', '默认值')
,默认值可选,返回输入的字符串 confirm:let 变量=confirm('提示信息')
,显示一个带有"确定"和"取消"按钮的对话框,返回布尔型 readline:读取输入的提供接口
javascript
import * as readline from "readline" //导入readline模块
let rl = readline.createInterface({
input: process.stdin,
output: process.stdout
})
rl.question('提示信息', (形参)=>{
函数体
rl.close();
}) //输入内容作为实参传给回调函数
多行输入
line事件:rl.on('line', (input)=>{})
,在触发line事件(如回车、返回等)执行回调函数,一般要设置一个结束条件执行 rl.close()
close事件:rl.on('close', ()=>{})
,在触发close事件(如执行rl.close()等)执行回调函数
输出
console.log('输出信息')
选择结构
1.if语句
scss
if(条件){
执行代码
}else if(条件){
执行代码
}else{
执行代码
}
2.switch语句
跳转到对应值的位置向下开始执行
arduino
switch(变量){
case 值1:
代码;
break;
case 值2:
代码;
break;
}
循环结构
1.while循环
scss
while(条件){
执行代码
}
2.do while循环
arduino
do{
执行代码
}while(条件)
3.for循环
scss
for(初值设置; 循环执行; 终止条件){
执行代码
}
4.for of循环
用于遍历可迭代对象(如数组,字符串)中的元素
scss
for(let i of 可迭代对象){
执行代码
}
5.for in循环
用于遍历可迭代对象的角标,对象[i] 才指代对应元素
scss
for(let i in 可迭代对象){
执行代码
}
break :退出当前循环体,只退出最里层的循环 带标签的 break:退出标签下的所有循环体,即
kotlin
lab:
循环1{
循环2{
break lab;
}}
continue:结束当前循环,进入下一次循环
带标签的continue:结束当前循环,进入标签下最外层的下一次循环
lab:
循环1{
循环2{
continue lab;
}}
函数定义
1.使用function定义函数
lua
function 函数名(形参){
函数体;
return 返回数据;
}
函数名(实参)
2.将匿名函数赋值给变量,通过变量调用
javascript
let 变量=function(形参){
函数体;
return 返回数据;
}
变量名(实参)
3.箭头函数省略function
javascript
let 变量=(形参)=>{
函数体;
return 返回数据;
}
只有一个形参时可以省略小括号 只有一句代码时可以省略大括号和return 返回对象时不能省略大括号和return,但用小括号代替大括号时可以省略return
嵌套函数
在函数内定义的函数,作用域仅限外函数内 闭包 :函数内部定义变量,外部利用返回值获取内部变量的值,内部变量被外部引用不会因计算而改变 闭包函数:将嵌套函数名作为返回值,即可在外部使用,保护函数的参数在执行完不被销毁,会记忆改变。可用于多级参数传入,多次调用同一函数并记忆改变,即
csharp
function outside(){
function inside(){
嵌套函数体
}
return inside
}
let result=inside
result()
result=null
回调:一个函数作为参数传入另一个函数,可用于装饰函数,附加功能,即
scss
function a(){
函数体
}
function b(func){
func()
}
b(a)
也可在调用时传入匿名函数作为参数
javascript
function a(func){
函数体
}
a(function(){
函数体
})
函数参数
默认参数 :在形参设定时进行默认赋值,当实参未对应到时使用默认值 可变参数 :不设置形参,则实参会存放在arguments类数组对象中,在函数体中用索引arguments[i]调用对应参数 剩余参数 :在形参设定时最后一个形参使用...arg
形式,把对应后剩余的实参存在arg数组中
数组
数组中元素可以不同 let a=[]
创建数组,用索引调用元素 a[i]
返回数组中第i个元素(从0开始) a[i]=b
修改数组的第i个元素,i大于数组元素数则将元素添加在末尾 a.length
返回数组长度 a.toString()
返回以逗号分隔的连接所有数组元素的字符串 a.join(' ')
返回以指定字符分隔的连接所有数组元素的字符串 a.push(b)
在数组末尾添加一个元素 a.pop()
删除并返回数组最后一个元素 a.shift()
删除数组的第一个元素 a.unshift(b)
在数组首添加一个元素 a.indexOf(b)
返回元素的索引 a.slice(i, j)
返回从i到j的切片数组,左闭右开 a1.concat(a2)
返回a1接a2的数组 forEach方法:a.forEach(func)
,遍历数组,以元素、索引、数组的顺序传给回调函数,即a.forEach(function(value, index, array){})
filter方法:定义一个以元素、索引的顺序作为形参,返回布尔型的规则函数,a.filter(func)
进行过滤留下布尔型为true的元素 every方法:同上定义一个规则函数,a.every(func)
验证全部元素是否满足规则,返回布尔型(全部满足返回true,否则返回false) some方法:同上定义一个规则函数,a.some(func)
验证全部元素是否满足规则,返回布尔型(全不满足返回false,否则返回true) find方法:同上定义一个规则函数,a.find(func)
返回第一个满足规则的元素值 findindex方法:同上定义一个规则函数,a.findindex(func)
返回第一个满足规则的元素索引,全不满足返回-1 map方法:定义一个以元素、索引的顺序作为形参,返回新元素值的规则函数,a.map(func)
从左往右对每一个元素执行函数,返回一个新的数组,不会改变原数组 reduce方法:定义一个以累加器、元素、索引、数组的顺序作为形参,返回计算规则的规则函数,a.reduce(func, 累加器初值)
从左往右对每一个元素执行函数,返回值加给累加器;a.reduce(func)
未设定初值默认是0,且从索引为1的元素开始;累加器初值设定可以是数值、字符串、数组、对象等 reduceRight方法:基本同上,唯一不同点是从右往左执行 splice方法:a.splice(索引, 0, 元素值)
为0则将元素从索引处插入数组,a.splice(索引, 1)
为1则将索引处的元素从数组中删除并返回 sort方法:a.sort()
默认将数组升序重排,定义比较函数a.sort((a, b)=>a-b)
,a-b为升序,b-a为降序;元素为对象时,可用a.键 和b.键 确定排序参考的值 reverse方法:将数组逆序重排
多维数组 :数组的元素还是数组 数组展开 :c=[...a, ...b]
数组中在是数组的元素前加...将数组内的元素展开降维
对象
使用大括号创建,由属性(键值对key: value
)组成;属性可以是数值、字符串、数组、函数、对象等 对象.键
返回相应的值,可以进行修改和增加 '键' in 对象
判断属性是否存在,返回布尔型 delete 键
删除对应属性 对象构造器:创建类型相同的多个对象
javascript
function 构造器(形参){
this.键=值
在构造器中用this.键代指值进行操作
}
let 对象=new 构造器(实参)
创造对象后用 对象.键 代指值进行增删改和调用操作
对象原型 :用构造器.prototype.键=值
为构造器增加属性,已创建的对象也会同步增加属性 对象解构赋值 :let {变量 ,变量}=对象
,按顺序将属性解构赋值
类
由构造器和方法组成
javascript
class 类名{
constructor(参数){
this.键=值
}
函数(形参){
函数体
}
}
let 实例=new 类(参数)
可用类.prototype.键=值
为类添加属性或方法
私有成员 :无法在类外部访问;以#开头,在构造器外先声明,在构造器中通过 this.#私有成员
调用,可以是变量也可以是函数 静态成员 :通过 static 静态成员
进行声明,类.静态成员 进行调用修改
外部访问私有成员
Getter 方法和 Setter 方法:
csharp
class a{
#b;
constructor(b){
this.#b=b;
}
get b(){
return this.#b;
} //通过Getter方法输出私有成员
set b(b){
this.#b=b;
} //通过Setter方法修改私有成员
}
let c=new a(0);
a.b=1; //调用的是Setter方法,将#b赋值为1
d=a.b; //调用的是Getter方法,返回#b的值
继承
子类可以使用父类的全部属性和方法 用 class 子类 extends 父类{}
继承,在子类中用 this.属性
可以直接调用父类属性(父类私有成员不可被访问),super(参数)
调用父类的构造器,super.函数()
调用父类的函数,构造同名函数可以覆盖
模块
一个js文件就是一个模块,用export导出,然后可以用import导入 导出可以用 export let 导出量
导出单个量,也可定义后 export {导出量, 导出量}
一次导出多个量,函数、对象、类只需导出对应的名 导入时可用 import {导入量 as 重命名, 导入量 as 重命名} from '路径'
导入并重命名 导入整个模块用 import * as 模块 from '路径'
,则用 模块.变量
进行调用,对核心模块可以将'路径'替换为模块名 默认导出 :一个模块只能有一个默认导出,在导入时自动重命名,通常是匿名导出(匿名函数export default function(){}
、匿名对象export default {}
、匿名类export default class{}
) require方法:用 let 重命名=require('模块名')
导入核心模块,let 重命名=require('路径')
导入文件模块
文件
同步操作:按顺序执行 异步操作:同时执行不按顺序,执行时间不确定,在同时输入输出的情景下可能由于执行时间错位出错,同时过多的回调函数造成程序不易读
先导入fs模块 let fs=require('fs')
获取文件信息:文件大小,创建时间,修改时间等 同步获得文件信息:let stats=fs.statSync('路径')
异步获得文件信息:fs.stat('路径', (err, stats)=>{})
将报错信息和文件信息作为实参传给回调函数
读写文件:read只读,write覆盖,append追加 同步:
kotlin
let data=fs.readFileSync('路径'); //将文件内容读取到data变量中
fs.writeFileSync('路径', data); //用data中的内容覆盖文件,文件不存在则创建新文件
fs.appendFileSync('路径', data); //在文件末尾追加data中的内容,不存在则创建
异步:
javascript
fs.readFile('路径', (err, data)=>{}) //读取文件内容并作为实参传给回调函数
fs.writeFile('路径', data, (err)=>{}) //用data中的内容覆写文件,出现报错则将报错内容传给回调函数
fs.appendFile('路径', data, (err)=>{}) //在文件末尾追加data中的内容,出现报错则将报错内容传给回调函数
分段读写 方式: r读取;r+读写;rs同步读取;rs+同步读写;文件不存在则报错 w写入;w+读写;a追加;a+读写追加;文件不存在则创建 wx写入;wx+读写;ax追加;ax+读写追加;文件已存在则写入失败 同步读写:
ini
let fs = require("fs");
let buf=new Buffer.alloc(10); //开辟指定大小的缓冲区,数据将先写入缓冲区
let file=fs.openSync('路径', '方式'); //以所需方式打开文件
let len=fs.readSync(file, buf, 0, buf.length, null); //读取文件,接收文件变量、缓冲区、指针偏移量、一次读取长度、开始读取位置(null则不动)
fs.writeSync(file2, buf, 0, len, null); //写入文件,接收文件变量、缓冲区、指针偏移量、一次写入长度、开始写入位置(null则不动)
fs.closeSync(file); //需要手动关闭文件
异步读写:
javascript
let fs = require("fs");
let buf=new Buffer.alloc(10); //开辟指定大小的缓冲区,数据将先写入缓冲区
let file=fs.open('路径', '方式', (err, fd)=>{}); //以所需方式打开文件,将报错和文件句柄传入回调函数
let len=fs.read(file, buf, 0, buf.length, null, (err, br, buf)=>{}); //读取文件,接收文件变量、缓冲区、指针偏移量、一次读取长度、开始读取位置(null则不动)、回调函数(报错,读取字节数,缓冲区)
fs.write(file2, buf, 0, len, null, (err, bw, buf)=>{}); //写入文件,接收文件变量、缓冲区、指针偏移量、一次写入长度、开始写入位置(null则不动)、回调函数(报错,写入字节数,缓冲区)
fs.close(file); //需要手动关闭文件
异步操作
Promise
由异步函数返回的指示异步操作所处状态的对象,有三种状态:pending未决断;fulfilld已决断;rejected已拒绝 适用于解决回调函数过多的情况 创建 :let promise=new Promise((reslove, reject)=>{})
接收一个以reslove, reject为参数的回调函数,函数内调用reslove(参数),状态更新为fulfilled;调用reject(参数),状态更新为rejected;也可直接 let promise=Promise.resolve(参数)
返回给定状态的Promise对象 使用 :promise.then((参数)=>{}).catch((参数)=>{}).finally((参数)=>{})
,根据状态执行,then方法的回调参数由reslove的参数提供,catch方法的回调参数由reject的参数提供,无论何种状态均会执行finally方法;一般用then方法作为前置异步函数执行完毕后的执行内容 all方法:接收Promise对象数组为参数,返回一个新的Promise对象;每个对象状态都是fulfilled,则新的Promise对象状态也为fulfilled,返回对象数组的参数结合的数组;有一个对象状态是rejected,则新的Promise对象状态也为rejected,返回第一个rejected对象的参数
ini
let p1=Promise.resolve(c1);
let p2=Promise.resolve(c2);
let p3=Promise.resolve(c3);
Promise.all([p1, p2, p3]).then(res=>{}).catch(err=>{});
race方法:接收Promise对象数组为参数,返回一个新的Promise对象;新的Promise对象状态与数组中第一个改变状态的对象改变后的状态一致,返回该对象的参数
async和await:将Promise同步化
async定义函数表示函数内有异步操作,await只能在async内使用,后面跟一个返回Promise对象的表达式/函数;await将阻塞函数直到其后Promise对象调用reslove方法,返回resolve方法的参数
javascript
function func2(){
函数体
return new Promise((resolve)=>{reslove(参数)})
}
async function func1(){
await func2()
}
TS
- 将js扩展出类型,运行前需要tsc .ts编译
- 原始数据类型:number,boolean,string,null,undefined,void,any
- 定义变量:let 变量: 类型=数据
- 强制类型转换:<类型>数据
- null、undefined只有一种取值(即该类型)
- void常作为函数返回值类型,定义void类型变量可用undefined赋值
- any为任意类型,可以赋值和被赋值任意类型的数据
- 联合类型:具有多种类型的变量,取值可以在多种类型中 let 变量=类型|类型|类型
函数
函数的参数和返回值也要明确类型 function 函数(参数: 类型): 返回值类型{},函数体内不能return具体的值 箭头函数 let 函数=(参数: 类型): 返回值类型=>{}
可选参数:只能在参数列表右侧,用 可选参数?: 类型
声明 默认参数:同样只能在参数列表右侧,用 参数: 类型=默认值
声明 剩余参数:只能是参数右侧最后一个,用 ...剩余参数
声明,接收所有剩余的实参形成数组
数组
定义时要明确类型,数组内元素须与数组类型一致 let 数组: 类型[]=[ , ]
多维数组 :let 数组: 类型[][]=[[ , ],[ , ]]
,多维数组可以不规则(内部数组的元素数无需保持一致)
接口
用接口定义对象类型
csharp
interface 对象{
属性键: 类型
可选属性键?: 类型
readonly 只读属性键: 类型 //创建后无法修改
函数: (参数: 类型): 返回值类型
}
let 变量: 对象={
键: 值
函数: (参数: 类型): 返回值类型=>{函数体}
}
可以用 interface 子接口 extends 父接口
继承接口
元组 :可存放不同类型的元素,用中括号定义 let 元组: [类型, 类型, 类型]=[ , , ]
枚举 :enum 枚举{选项=返回值}
,用 枚举.选项
输出对应返回值
类
定义时需要明确可见性 抽象类abstract :不能被实例化,只能被继承;包含抽象方法只能定义不能实现(无函数体),继承的子类必须实现父类抽象方法(补上函数体);非抽象方法可以在抽象类中实现,子类可以使用或覆盖 可见性:public默认可见;protected只能在类或子类内部访问;private只能在类内部访问,子类也不行
csharp
abstract class 父类{
protected 属性: 类型 //可在类及子类内部访问
private 属性: 类型 // 仅可在类内部访问
public constructor(参数: 类型){
public 属性: 类型
}
public abstract func(): void{} //抽象方法在抽象类中不实现,在子类中必须有实现
public func2(): void{
函数体
}
}
class 子类 extends 父类{
protected 属性: 类型
private 属性: 类型
public constructor(参数: 类型){
super() //调用父类构造器
this.属性=数据
}
public abstract func(): void{
函数体
} //实现父类的抽象函数
}
let 实例: 类=new 类(参数)
泛型
将类型作为参数,为不同类型的输入执行相同的代码,可在函数、类、接口等使用 泛型函数 :function 函数<T>(参数: T):T{}
,函数<类型>(参数)
调用 可以有多个泛型参数:function 函数<T, U>(参数: T, 参数: U):[T, U]{}
泛型接口 :interface 接口<T>{属性键: T}
,let 对象: 接口<类型>={键: 值}
泛型类 :class 类<T>{属性: T}
,class 子类 extends 父类<类型>{}
继承 泛型约束:通过继承接口让输入的泛型必须是具有某一属性的类型
typescript
interface str{
length: number
}
function a<T extends str>(s: T){
console.log(str.length)
} //当类型不具有length属性时会报错