字符串的扩展方法
const message = `Error: foo is not defined.`
console.log(message.startWith('Error')) // true
console.log(message.endWith('.')) // true
console.log(message.includes('foo')) // true
参数默认值
function foo(enable=true) {
console.log(enable)
foo() // true
function foo (...args) { // 只能出现在形参的最后一位,只能使用一次
console.log(args)
foo([1,2,3])
spread 展开数组
const arr = ['a','b','c']
console.log(...arr)
function inc (number) {
return number + 1
const inc = (m,n)=> m+n
console.log(inc(1,3)) // 3
// 不会改变this的指向
const person = {
name: 'tom',
say: ()=>{
console.log(this.name)
sayAsync: function() {
setTimeout(()=>{
console.log(this.name)
person.say() // undefined
对象字面量的增强
const obj = {
name:'zhangsan',
foo(){ // 等价于:function声明
[name]:100 // 变量名也可动态
对象扩展方法
Object.assign(obj, target) // 后面对象覆盖前面的
Object.is(+0, -0) // true
Object.is(NaN, NaN) // true
// Object.definedProporty() 只能监听到对象的读写 对数组的监听是重写方法$set
Proxy
// 能监视到更多对象操作 或对对象方法的调用 更好的支持数组监听 是以非侵入方式监管对象的读写
const person = {
name:'aaa',
age: 90
const personProxy = new Proxy(person, {
get(target, property) {
return property in target ? target[property] : 'default'
console.log(target, property)
// return 10
set(target, property, value) {
if(property==='age') {
if(!Number.isInteger(value)) {
throw new TypeError(`${value} is not an int`)
target[property] = value
console.log(target, property, value)
personProxy.age = 25
personProxy.gender = true
// console.log(personProxy.name) // 10
// console.log(personProxy.name) // aaa
const list = []
const listProxy = new Proxy(list, {
set (target, property, value) {
console.log('set', property, value)
target[property] = value
return true
listProxy.push(100)
Reflect
// 统一的对象操作API 内部封装了一系列对对象的底层操作 成员方法就是Proxy对象中对应的方法
const obj = {
name:'aaa',
age: 90
// console.log('name' in obj)
// console.log(delete obj.age)
// console.log(Object.keys(obj))
console.log(Reflect.has(obj, 'name'))
console.log(Reflect.deleteProperty(obj, 'age'))
console.log(Reflect.ownKeys(obj))
Promise
class 类
function Person(name) {
this.name = name
class Person {
constructor(name) {
this.name = name
say() {
console.log(this.name)
static create(name) { // 静态成员 static
return new Person(name)
const n = new Person('SUMMER')
const tom = Person.create('tom')
tom.say()
// 类的继承
class Student extends Person { // 继承person所有参数
constructor(name, number) {
super(name) // 调用它就是调用父类的所有方法
this.number = number
hello() {
super.say()
console.log(this.number)
const s = new Student('tom', 100)
console.log(s)
Set 数据结构 集合
const s = new Set()
s.add(1).add(2).add(3)
s.forEacg(i=>console.log(i))
s.size
s.has(100) // false
s.delete(3)
s.clear()
// 数组去重 new Set
const arr = [1,2,1,3,4,5]
const result = Array.from(new Set(arr))
const result = [...new Set(arr)]
// 可以把Object作为键 对象只能用字符串做键
const obj = {}
obj[true] = 'value'
obj[123] = 'value'
obj[{a:1}] = 'value'
const m = new Map()
const tom = {name: 'tom'}
m.set(tom, 90)
console.log(m)
m.has()
m.delete()
m.clear()
m.forEach((value,key)=>{
console.log(key)
Symbol // 表示一个独一无二的值
// 通过Symbol创建的值都是独一无二的
// 可以作为对象的属性名
// 创建私有成员
Iterator
// for of 循环 可以遍历所有的有Iterator的
const arr = [1,2,3]
for(const item of arr) {
console.log(item)
// 实现可迭代接口 Iterable
const obj = {
store: ['foo','bar','baz'],
[Symbol.iterator]: function () {
let index = 0
const self = this
return {
next: function () {
const result = {
value: self.store[index],
done: index >= self.store.length
index ++
return result
for (const item of obj) {
console.log('循环体')
// 作用:对外提供统一遍历接口 适合于任何数据结构
生成器 generator 异步编程解决方案
function * foo () {
console.log('111')
yield 100
console.log('222')
yield 200
console.log('333')
yield 300
const res = foo()
console.log(res) // 打印生成器对象
console.log(res.next()) // 实现了迭代器接口
const generator = foo()
console.log(generator.next()) // 遇到yield暂停 111 {value: 100, done: false}
console.log(generator.next()) // 遇到yield暂停 222 {value: 200, done: false}
console.log(generator.next()) // 遇到yield暂停 333 {value: 300, done: false}
console.log(generator.next()) // 遇到yield暂停 {value: undefined, done: true}
生成器应用
案例:使用generator函数实现iterator方法
const todos = {
life: ['吃饭','睡觉'],
learn: ['学习'],
work: ['摸鱼'],
[Symbol.iterator]: function * () {
const all = [...this.life, ...this.learn, ...this.work]
for (const item of all) {
yield item
for (const item of todos) {
console.log(item)
ECAMAScript2016
includes
[1,2,3].includes(2) // true
[1,2,3].includes(NaN) // false
指数运算符
console.log(Math.pow(2,3)) // 以前指数运算
console.log(2 ** 10) // 现在指数运算
ECAMAScript2017
Object.values、Object.entries
Object.values(obj)
Object.entries(obj)
new Map(Object.entries(obj))
getOwnPropertyDescriptors
const p1 = {
firstName: 'lei',
lastName: 'wang',
get fullName() {
return this.firstName+' '+this.lastName
console.log(p1.fullName)
const p2 = Object.assign({}, p1) // 复制的时候值当做普通属性复制
p2.firstName = 'zhangsan'
console.log(p2) // 打印的还是p1内容
const desc = Object.getOwnPropertyDescriptors(p1)
console.log(desc)
const p2 = Object.definedPropories({}, desc)
p2.firstName = 'zhangsan'
console.log(p2.fullName)
padStart/padEnd 补齐
const books = {
html: 3,
css: 10,
javascript: 120
for(const [name, count] of Object.entries(books)) {
console.log(`${name.padEnd(16, '-')}|${count.toString().padStart(3, '0')}`)
函数参数中添加尾逗号
function foo (
bar, baz,) {
TypeScript
TypeScript解决JavaScript类型系统的问题
编程语言从类型安全角度分为强类型与弱类型
从类型检查角度分为静态类型与动态类型
强类型不允许任意类型的隐式类型转换 // 编译阶段就不允许
静态类型一个变量声明是就是确定的,并且不允许修改
强类型优点
错误更早暴露
代码更智能,编码更准确
重构更牢靠
减少不必要的类型判断
const hello = (name: string) => {
console.log(name)
console.log('jdsodj')
const a: string = ''
const b: number = 1
const c: boolean = true
const d: void = undefined
const e: null = null
const f: undefined = undefined
enum postStatus {
startus0 = 0, // 如果是数字还会自增
startus1,
startus2
// postStatus[0]
// postStatus.startus0
函数类型 FunctionType
const s = (name: string, age?: number) => {
console.log(name+age)
s('hahha')
隐式类型推断
let age = 10 // 推断为number
let foo // 推断为any
类型断言 as <>
const nums = [1,2,3]
const res = nums.find(i=>i>0)
const num = res as number
const num2 = <number>res // <> jsx下冲突 建议用as
接口 interface 约束对象的结构
interface Post {
title: string
num: number
subtitle?: string // 可选成员
readonly summary: string // 只读成员
function printPost(post: Post) {
console.log(post.title)
console.log(post.num)
printPost({
title: 'ahhha',
num: 1000,
summary: 'ok'
类 - 描述一类事物的具体特征 ts增强了class的语法
class Person {
public name: string // 默认public
age: number
private weight: number // 私有属性
protected readonly gender: boolean // protected只允许在子类中访问的成员 readonly只读
constructor (name: string, age: number) { // 构造函数也可设置为private protected
this.name = name
this.age = age
say(msg: string):void {
console.log(`${this.name}: ${this.age}${msg}`)
class Student extends Person {
constructor(name: string, age: number) {
super(name, age)
console.log(this.gender)
implements 扩充
interface Eat {
eat (food: string): void
interface Run {
run (distance: number): void
class Dog implements Eat, Run {
eat (food: string):void {
console.log(food)
run (distance: number):void {
console.log(distance)
class Pig implements Eat, Run {
eat (food: string):void {
console.log(food)
run (distance: number):void {
console.log(distance)
抽象类 -只能被继承
abstract class Animal {
eat(food: string):void {
console.log(food)
abstract run (distance: number): void
泛型 定义的时候不指定类型 调用的时候再确定类型
function createArr<T> (length: number, value: T): T[] {
const arr = Array<T>(length).fill(value)
return arr