2022-02-21【学习】ES6&TS重点语法学习

本文列举了一些在实际使用中比较常见,而又比较陌生的语法(主要集中在ES6的特性上),做好一些铺垫和基础。
JavaScript 参考-JavaScript 标准内置对象-Array
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array

介绍

ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准。因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015。在 ES5 的基础上新增了很多特性,完善了自身结构,解决了很多问题,更容易使用了。

TS - TypeScript,有类型的 JavaScript,通过增加静态类型检查来实现“强类型”特性,是 JavaScript 的超集,也可以通过被编译成低版本的 ES3 兼容所有运行环境。

TS 出现比ES6早,最初 TS 中添加了很多语法规范和特性,但随着 ES 的版本迭代,TS 的很多语法特性都被追平,目前集中在强类型上,对于客户端或熟悉使用编译型语言的同学来说,这种强类型模式比较熟悉,所以篇幅会比较小。

TypeScript和ES6的区别

1、TypeScript是一种免费的开源编程语言,由Microsoft开发和维护。ES6是ECMAScript(ES)的一个版本,它是ECMA 国际标准化的脚本语言规范。
2、TypeScript支持所有原始数据类型,ES6不支持。
3、变量作用域
TypeScript有3个作用域:全局作用域、类作用域、局部作用域。
ES6有2个作用域:全局作用域、局部作用域。
4、模块
在TypeScript中,模块有两种类型内部和外部模块,在ES6中,模块分为导入模块和导出模块。
5、ES6主要倾向于在需要的工具或小型项目中进行构建。如果我们需要强大的测试工作流程,我们需要记住一件事,那么我们必须使用ES6。

下面会先介绍 ES6,在此基础上,再介绍TS额外的部分。

ES6

一 变量声明

之前: var
现在:let(变量) 和 const(常量)
var 问题:
1.var 全局作用域,易出错;let const 块级作用域

{
    let a = 10; 
    var b =20;
}
a //调用失败 let 声明的变量的为局部变量,只在{....}的块作用域生效。
b //20      var 声明的变量为全局变量,在全局作用域生效

// example 2
var s = "foo"
if (true) {
  var s = "bar"
}

s // s=bar

2.const可定义常量

const a = 10; 
a = 20; //再次赋值失败 const创建的变量为常量,一旦声明了就不能改变

二 解构赋值

变量的解构赋值为ES新推出的特性,指的是ES6允许按照一定的模式从数组或对象中取出值,对变量进行赋值。 如果解构不成功,变量的值就等于undefined。

# 数组解构
let [a,b,c]  = [1,2,3]  这种写法称为模式匹配,只要 “两边”  结构一致即可赋值。
console.log(a) //1
console.log(b) //2
console.log(c) //3

# 部分解构不成功
let [a,b] = [1] 
console.log(a) //1
console.log(b) //undefined 部分解构不成功

// 默认值
let [a,b=3] = [1]
console.log(a) //1
console.log(b) //3

# 对象解构
let node = {            
    sex:'fmale',
    age:10
}
let {sex,age} = node;
console.log(sex) //fmale 对象解构,对于内置对象同样可以。
console.log(age) //10

# 函数参数的解构赋值
function add([x,y]){
    return x + y;
}
let value = add([1,2,3,4,5,6]) 
value //3 函数的参数解构赋值  形容 let [x,y] = [1,2,3,4,5,6]

# 数值的解构赋值
let [a,b,c] = 123
console.log(a) //1 数值解构
console.log(b) //2
console.log(c) //3

# 字符串的解构赋值
let [a,b,c] = '123';
console.log(a) //1
console.log(b) //2
console.log(c) //3

//原则上 只要两边的结构一致都可以进行解构赋值。

三 函数

箭头函数

去掉function,用箭头链接方法体

  1. 有且仅有一个参数,()可以不写
  2. 如果有且只一个语句,return 和 {}可以不写
let a = function(x){
  return x * 2
}
a(4) // 8

// 变化1
let a = (x)=>{
  return x * 2
}
a(4) // 8

// 变化2
let a = x=>{
  return x * 2
}
a(4) // 8

// 变化3
let a = x=> x * 2
a(4) // 8

// 作为回调,在入参中简洁表达
setTimeout(() => {
    // to do
}, 500)

this

js 里 this 使用非常复杂,就不展开说。直接说结论:
普通函数里 this 在函数调用时才被赋值,this 等于函数执行时候的执行环境;
使用箭头函数时,this 等于定义时的环境;
详见:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions

四 参数扩展

打开参数

数组展开

var arr = [1, 2, 3];
var arr2 = [...arr]; // ...arr 等价 [1,2,3]
arr2.push(4);
console.log(arr2)// [1, 2, 3, 4]

json展开

let obj1 = {
  foo: 'bar',
  x: 42
};
let obj2 = {
  foo: 'new bar',
  y: 13
};
let clonedObj = { ...obj1 };
let mergedObj = { ...obj1, ...obj2 }; // merge 后加的参数会覆盖先加入的参数
console.log(clonedObj) // {foo: "bar", x: 42}
console.log(mergedObj) // {foo: "new bar", x: 42, y: 13}

收集参数

函数的剩余参数

function add(a,...values){
    var total = 0;
    for(var val of values){
        total +=val;
    }
    return total;
}
add(1,2,3,4,5); //2+3+4+5 = 14

五 数组的操作方法

这里记录的很全: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array

挑几个常见的说下:
map() 映射 一一对应
reduce() 收集 出一个结果
filter() 过滤 留下一部分
foreach() 遍历 每一个都访问

let array = [1, 4, 9, 16];

// pass a function to map
let map1 = array.map(x => x * 2)
let map2 = array.reduce((x, y) => x + y)
let map3 = array.filter(x => x > 4)
let map4 = array.forEach(x => console.log(x))

console.log(map1);// expected output: Array [2, 8, 18, 32]
console.log(map2);// 30
console.log(map3);//  [9, 16]
console.log(map4);// 1, 4, 9, 16

<meta charset="utf-8">

六 字符串模板

反单引号 `` 围起来字符串,可以动态添加变量

# 模板字符串中 嵌入变量
let [a,b] = ['jack','Bob']    
let text = `hello ${a},I'm ${b}` // 美元符+花括号将变量替换到字符
text //hello jack, I'm Bob

# 模板字符串中进行逻辑运算
let [a,b] = [1,2]
let result = `${a} + ${b} = ${a+b}`
result //1 + 2 = 3            

七 JSON 序列化操作

调试的时候很常用,有坑点单独说下。
JSON.stringify()
JSON.parse() // 需要标准化的JSON

// 不是标准化json,key不是字符串
let json = {
    a:'foo',
    b:'bar',
    c:100
}
JSON.stringify(json) //"{"a":"foo","b":"bar","c":100}"

let str = '{"a":"foo","b":"bar","c":100}' 
// let str = "{'a':'foo','b':'bar','c':100}" key一定要有"双引号",反过来也不行
JSON.parse(str)

八 异步编程

异步操作,回调地狱
代码块

<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
    let user
    // ajax get请求数据
    $.get('https://api.github.com/users', data=>{
        console.log('fetched all users')
        user = data[0].login
        // 数据校验正确,再请求下一步
        $.get(`https://api.github.com/users/${user}/repos`, data=>{
            console.log('fetched all repos')
            console.log(data)
         })
    })
</script>

image

promise

作用:进行统一的异步封装

let promise = new Promise(function (resolve, reject) {
    // 做一些异步操作
    if(/*异步操作成功*/){
        //该value传入回调函数中
        resolve(result);
    }else{
        //该error传入回调函数
        reject(error);
    }
})

promise.then(result=>{
    console.log(result)
}).catch(err => {
    console.log(err)
}).finally(()=>{
  // 最终执行的代码段
})

//其他
1.Promise.all(arry)  // all 等待所有异步操作执行完成 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
2.Promise.race(arry) // race 任一执行完成后就结束 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/race

再看上面的回调地狱,可以用阶段性返回 promise 对象来解决循环嵌套

<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.16.2/axios.min.js"></script>
<script>
  axios.get('https://api.github.com/users') // 返回一个 Promise
    .then(reponse => {
      let username = reponse.data[0].login
      // 解析正确返回下一个请求的Promise
      return axios.get(`https://api.github.com/users/${username}/repos`)
    })
    .then(reponse => {
      console.log(reponse.data)
    })
    .catch(err => {
      console.log(err)
    })
</script>

async/await

更直观的语法,将异步变同步,ES2017(es8)

async function myFetch() {
  let reponse = await axios.get('https://api.github.com/users') // 返回一个 Promise
    let username = reponse.data[0].login
  let repos = await axios.get(`https://api.github.com/users/${username}/repos`)

  // 操作 repos ...
}

async/await 原理:可以将函数执行暂停,通过将函数切换成多个小函数来实现。
更多参考:https://developer.mozilla.org/zh-CN/docs/learn/JavaScript/%E5%BC%82%E6%AD%A5/Async_await

九 模块

导出 export:独立模块的对象、函数、值是无法被其他文件访问到的,如果要让外部访问到,需要使用 export 导出
相对的,要使用其他模块内容,就需要导入 import 相关内容

// module "my-module.js"
function cube(x) {// 函数
  return x * x * x;
}

const foo = Math.PI + Math.SQRT2;// 常量

var graph = {
    options: {
        color:'white',
        thickness:'2px'
    },
    draw: function() {
        console.log('From graph draw function');
    }
}
export { cube, foo, graph };

// --------------- another file ---------------
import { cube, foo, graph } from 'my-module.js';

graph.options = {
    color:'blue',
    thickness:'3px'
};

graph.draw();
console.log(cube(3)); // 27
console.log(foo);    // 4.555806215962888

此外还有默认导出,即我们在 vue 里常见的 export default ,只是将当前模块做默认导出,没有其他特殊含义。

// module "my-module.js"
export default function cube(x) {
  return x * x * x;
}

// --------------- another file ---------------
import cube from './my-module.js';
console.log(cube(3)); // 27

TS
列举下实际开发中,常遇见的TS里有的,但是 ES6 所没有的特性,总结下来就是:

  1. 类型(核心)
  2. 面向对象增强
    这里只是简单列举,一些细节和JAVA或OC使用都类似,如果遇到报错,再查文档 https://www.tslang.cn/docs/handbook/basic-types.html 找找原因,会比较好懂

一 类型

1.强类型

不同于大部分编译型语言,TS 的类型是写在变量名后面,通过冒号: 连接的

const name:String = "Hello World"

TypeScript 里也有现代语言都具备的类型推断特性(Java要10以上的版本),不需要每一个变量都声明类型。

2.支持联合类型

多种类型用竖线 | 连接,表示该变量可以是多种类型的

function padLeft(value: string, padding: string | number) {
    // ...
}
function getSmallPet(): Fish | Bird {
    // ...
}

3.元组

swift 里也有,允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。 比如,你可以定义一对值分别为 string和number类型的元组。

let x: [string, number] = ['hello', 10];

4.枚举

这个都懂

enum Color {Red, Green, Blue}

5.特殊类型

  • any —— 表示任何类型
  • void —— 表示没有类型,用于修饰函数返回值类型,作为变量类型时,没有什么用
  • never —— 表示的是那些永不存在的值的类型,和 null 或 undefined 不同,他用来表示类型,而不是具体的值

6.函数类型

在基础函数上,多了入参类型和返回值类型

//函数类型(入参的类型,返回值类型): 返回值类型 
function(x: number, y: number): number { 
  // 函数体
  return x + y; 
};

声明一个函数的变量 myAdd ,也需要指定这个函数的类型,函数类型比较复杂点,分成入参类型和返回值类型。
(入参1:入参1类型, 入参2:入参2类型) => 返回值类型

代码块

// 变量名    函数类型(入参的类型,返回值类型)   =    入参的类型(俩 number)         返回值类型   函数体
let myAdd: (x: number, y: number) => number = function(x: number, y: number): number { return x + y; };
// 定义太长了,不写,也可以通过推断得出
let myAdd = function(x: number, y: number): number { return x + y; };

// 箭头函数基本没变,入参加了类型
let double = (e: number) => { return e * 2}

推断文档:https://www.tslang.cn/docs/handbook/type-inference.html

二 面向对象

1.接口

这个JAVA开发太熟悉了,但是在TS里,他更多的是用来创建 Model 数据模型

interface LabelledValue {
  label: string;
}

function printLabel(labelledObj: LabelledValue) {
  console.log(labelledObj.label);
}

加上可选,这种感觉就更明显了

interface SquareConfig {
  color?: string;
  width?: number;
}

2.类的Field支持修饰符

public 、private 、protected 这些老朋友不用多做介绍,再来个 readonly,相当于 final。

class Demo {
  private a: string;
  public b: string;
  protected c: string;
  readonly name: string; //相当于Java里的final,在初始化或构造函数里一定要被初始化,至多赋值一次
}

3.抽象类

abstract class Animal {
    abstract makeSound(): void;
    move(): void {
        console.log('roaming the earch...');
    }
}

参考内容

ES6:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference
TS手册:https://www.tslang.cn/docs/handbook/basic-types.html
TS参考: https://zhuanlan.zhihu.com/p/98709371

-孢子菌 2022年2月21日 15:01:04

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342