学习笔记---1.2ESMAScript

ES新特性

最主要的四个方面:

  • 解决原有语法上的一些问题或者不足
  • 对原有语法进行增强
  • 全新的对象、全新的方法、全新的功能
  • 全新的数据类型和数据结构

作用域

作用域:某个成员能够作用的范围

块级作用域:let关键词声明变量,在花括号范围内生效的块级作用域

let变量声明不会提升。

const定义恒量。所以声明时就需要赋值。const声明的成员不能被修改,指的是是不允许再修改指向新的内存地址,但成员的属性值是可以修改的。

解构

关键字:[]。还可直接在解构的位置=指定默认值。
…展开。但只能用于最后的位置

数组的解构通过位置一一对应来结构赋值。
对象的解构通过属性名来解构赋值。为避免属性名冲突的问题,还可以在等号左边赋值的位置指定获取属性的新属性名称。

const obj = {name:'a',age:18}

const {name } = obj
//指定name属性新的变量名
const {name:newname} = obj

字符串

模板字符串

关键字:``
支持换行和变量取值:插值表达式${变量}

带标签的模板字符串:用插值表达式分割,将字符串以数组形式传递成模板函数的参数。

const name = 'tom'
const  gender = true

function myTagFunc(string,name,gender){
	return string[0] + name + string[1] + gender + string[2]
}
const result = myTagFunc`hey,${name} is a ${gender}.`
//hey,tom is a trues
字符串扩展

startsWith、endWith、iscludes

参数

在形参定义时通过=设置默认值。
tips:定义多个参数时,需要传递默认值的参数需要定义在最后。

剩余操作符:…
…args能展开参数伪数组,还能展开数组。

const arr = ['foo','bar','zz']

console.log(...arr)
//foo bar zz

箭头函数:
(参数) =》 {函数体}

箭头函数没有this的机制。永远指向定义箭头函数的作用域上下文。

字面量的增强

对象属性为变量赋值,可以直接赋值而不再需要通过属性名来指定变量为其赋值;
还可以通过[]进行计算属性名赋值。

const bar = '123'

const obj = {
	foo:123,
	bar,
	[Math.random()]:123,
	[bar+12]:333
}
//{'12312':333,foo:123,bar:123,'0.654326543':123}

assign

assign(对象1,对象2):用对象2覆盖对象1,并返回对象1.

  • proxy
    可监听数组的相关操作;监视属性不会入侵到被监视对象本身。
  • realect

class类

实例方法:通过实例对象调用。静态方法:只能class自身调用,关键字static.

类的继承: class 子类名 extends 父类名. 在子类中通过super()继承父类构造器内的属性值。

class Person = {
	constractor(name){
		this.name = name
	}
	say(){
		console.log(`hi,my name is ${name}`)
	}
}

class student extends Person{
	constractor(name,number){
		super(name)
		this.number = number
	}
	hello() {
		super.say()
		console.log(`my school number is ${number})
	}
}

set

一个不重复的集合。类似于数组,但是数组中的数据不能重复。可用于去重。api:size、has、delete

map

键值对集合。类似于对象,但是键值可以不只是字符串。

const m = new Map()
const tom = {name:'tom'}

m.set(tom,90)
console.log(m) // Map {{name:'tom'} => 90}
console.log(m.get(tom)) //90

symbol

表示一个独一无二的值。用处:为对象添加独一无二的属性标志符。

for…of循环

遍历数组时,直接得到值。可以直接break退出循环。

遍历Map对象,得到键值对数组

const m = new Map()
m.set('foo','123')
m.set('bar','234')
for (const item of m){
	console.log(item)
}
//结果:
[ 'foo', 123 ]
[ 'sda', 234 ]

可迭代接口

iteraator对象实现可迭代接口。迭代器内部有一个next方法输出迭代器结果接口(IterationResult).迭代器结果接口需要返回值value和迭代状态done。

const obj = {
	[Symbol.iterator]: function(){
		return {
			next:function(){
				return {
					value:'aaa',
					done:true
				}
			}
	}
} 

生成器

避免异步编程中回调嵌套过深。关键字:*。也是通过nex t调用。

生成器函数返回一个生成器对象,通过next()方法执行函数体,遇到关键词yield时暂停执行,yield后面的值作为next方法的结果返回。下次再调用next方法,从暂停的位置继续执行。

function *foo(){
	console.log("sss")
	return 100
}

常用运用场景:发号器。

ES2016

includes、指数运算符:底数 ** 指数(eg:2 ** 10 = 1024)

ES2017

padStart、padEnd以指定字符补齐位数对齐。

const books = {
	html:5,
	css:12,
	js:1233
}

for(const [name,count] of Object.entries(books)){
	console.log(`${name.padEnd(16,'-')} | ${count.toString().padStart(3,'0')}`)
}
//结果
html------------ | 005
css------------- | 012
js-------------- | 1233

TypeScript

flow:类型检查器

关键字:冒号类型注解

  • 安装:
    npm安装:
    1.安装:pm install --g flow-bin (项目安装的话,把–g替换成-D)
    2.npm init -y(-y默认全部yes快速创建)创建package.json,在文件中scripts中添加:
“scripts":{
	"flow":"flow"
}
  • 使用命令
    npm run flow init 在项目路文件的根目录创建一个.flowconfig文件

npm run flow check 对所有文件夹进行类型检查

npm run flow 启动Flow服务

flow 执行flow检查

npm run flow stop 停止flow服务

  • 标记需要进行检查的文件:
    在被检查的文件最顶部添加@flow标识的注释对该文件进行检查
  • 编译移除注解
  • **方法一:**安装flow-remove-types:
    npm install --save-dev flow-remove-types
    运行flow-remove-types移除注解:
    yarn run flow-remove-types src/ -d lis/

src:需要移除注解的文件位置
lis:打包文件的存放位置

yarn run flow-remove-types . -d dist

**方法二:**运用babel操作编译
安装babel:npm install @babel/core @babel/cli @babel/preset-flow

配置babel:新建一个babelrc配置文件。文件内配置:

{
    "presets":["@babel/preset-flow"]
}

flow便捷安装:编辑器插件flow

flow原始类型

string、number、boolean、null、void、symbol

flow对结构对象注释:

数组:Array和number[]都表示只有数字的数组

TypeScript

  1. 初始化资源包:
    npm init 或者yarn init

  2. 安装typscript:
    yarn add typescript
    typescript文件扩展名是ts

  3. 编译ts文件:
    yarn tsc 文件名

typescript配置

yarn tsc --init自动生成配置文件tsconfig.json

outDir—编译结果输出文件夹
rootDir—源码文件夹

原始类型:
const a:string = 'foo'
const b:number = 100 //NaN Infinity
const c:boolean = true //false

//string、number、boolean都可以为空null.但一般检测是否为空,可以再配置文件中设置strictNullChecks.

const e:void = undefined
const f:null = null
const g:undefined = undefined
错误消息语言设置

在tsc命令后输入语言包名称

yarn tsc --locale zh-CN
作用域问题

将文件都以模块方式引入。或者放在立即执行的函数局部作用域中。

Object类型

不单指对象,而是指除了原始类型外的其他所有类型。

const foo:object = function(){}
//也可以用字面量语法的方式直接指定对象的每个属性类型
const obj:{foo:string,bar:numer} = {foo:'fod', bar:123}
数组类型
const arr1:Array<number> = [1,2,3]
const arr2:number[] = [1,2,3]
元祖类型

对数组的每个值进行字面量指定类型。

枚举类型

enum关键字定义枚举对象的值。枚举的值用等号赋值而不是冒号。

枚举类型编译后不会移除,会保存为键值对对象。如果希望被移除,可定义为常量枚举对象。

enum PostStatus{
	Draft = 0,
	Unpublished = 1,
	Published = 2
}

const post = {
	title:'pushlish',
	status:PostStatus.Published
}
函数类型

参数类型限制在参数后声明,返回值类型在参数括号后声明。可选参数在参数名后加问号,或者指定默认值(指定默认值的参数本身就是可选,但需要放在最后)。

function func1(a:number,b?:string):string{
	retrun 'func1'
}
任意类型any

可存放任意类型的值。但仍然是动态类型。

类型断言

变量 as 类型。告诉js变量为某种类型。

接口

对对象结构的一种约束。编译之后并不会保留。
可选成员:?
只读成员:readonly
动态属性:[prop:动态属性名类型]

interface Post {
 title:string
 content:string
 subtitle?:string
 readonly sunmmer:string
 [prop:string]:string
}    
const post:Post = {}

post.foo = 'value'
类与接口

interface定义接口约束对象结构。类中通过Implements实现接口约束,多个接口用逗号分割。

interface EatAndRun {
	eat(food:string):void
	run(distance:number):viod
}

class Person implements EatAndRun {
	eat(food:string):viod{
		console.log(`优雅地进餐:${food}`)
	}
	
	run(distance:number):viol{
		console.log(`直立行走${distance}`)
	}
}

class Animal implements EatAndRun {
	eat(food:string):viod{
		console.log(`呼噜地吃:${food}`)
	}
	
	run(distance:number):viol{
		console.log(`爬行${distance}`)
	}
}
抽象类

abstract class 类名。继承也是通过extends。

泛型

定义时不指定类型,使用时才传递具体类型。比如Array可以是数字也可以是字符串,为了使代码大成都复用。将泛型类型当做参数传递。

function creatArray<T>(length:number,value:T):T[]{
	const arr = Array<T>(length).file(value)
	return arr
}

const res = creatArray<string>(3,'foo')
类型声明

对于有些外部引入的第三方文件,可能没有指定类型声明。可以通过declare进行自定义声明。

import {camelCase} form 'lodash'
declare function camelCase (input:string):string
const res = camelCase('hello type')

js性能优化

GC:垃圾回收机制

找到内存中的垃圾、并释放和回收空间
GC中的垃圾:

  • 程序中不在需要使用的对象
  • 程序中不能再访问到的对象

常见GC算法:

  • 引用计数
  • 标记清除
  • 标记整理
  • 分代回收

引用计数

设置引用数,判断当前引用数是否为0.引用关系改变时修改引用数,引用数为0时立即回收。

优点:

  • 发现垃圾立即回收
  • 最大限度减少程序暂停

缺点:

  • 无法回收循环引用对象
  • 时间开销大

标记清除算法

  • 分标记和清除两个阶段
  • 遍历所有对象找标记活动对象
  • 遍历所有对象清除没有标记对象
  • 回收相应空间

优点:

可解决循环引用问题

缺点:

空间碎片化

标记整理算法

  • 是标记清除的增强
  • 标记阶段的操作和标记清除一致
  • 清除阶段会先执行整理,移动对象位置

V8

  • 是JavaScript执行引擎
  • 采用即时编译
  • 内存设限

v8中常见GC算法

  • 分代回收
  • 空间复制
  • 标记清除
  • 标记整理
  • 标记增量

内存分配

  • V8内存空间一份为二
  • 小空间用于存储新生代对象(32M|16M)
  • 新生代指的是存活时间较短的对象

新生代对象回收实现:

  • 回收过程采用复制算法+标记整理
  • 新生代内存区分为两个等大小空间
  • 使用空间为From,空闲空间为To
  • 活动对象存储于From空间
  • 标记整理后将活动对象拷贝至To
  • From与To交换空间完成释放
  • 拷贝过程中可能存在晋升
  • 晋升就是将新生代对象移动至老生代
  • 一轮GC还存活的新生代需要晋升
  • To空间的使用率超过25%

老生代对象:

  • 老生代对象存放在右侧老生代区域
  • 64位操作系统1.4G,32位操作系统70M
  • 老生代对象就是指存活时间较长的对象
  • 主要采用标记清除、标记整理、增量标记算法
  • 首先使用标记清除完成垃圾空间的回收
  • 采用标记整理进行空间优化
  • 采用增量标记进行效率优化

performance内存性能监测

可录制查看性能变化曲线

memory内存查看堆快照

代码优化

性能测试网站:https://jsperf.com

优化手段:

  • 慎用全局变量
  • 缓存全局变量
  • 通过原型对象添加附加方法
  • 避开闭包陷阱
  • 避免属性访问方法使用,直接使用属性名访问
  • for循环优化:
    循环长度缓存,避免每次循环前都去查找需要遍历的对象和长度。
//优化前:
for(var i =0;i<aBtns.length;i++{
	console.log(i)
}
//优化后
for(var i = 0,length = aBtns.length;i<length;i++){
	console.log(i)
}
  • 采用最优的循环方法

只是循环读取数据,并不操作时,性能:forEach>for>for in

  • 文档碎片优化节点添加

循环添加节点时,将要添加的父节点缓存,避免每次循环都多次往上查找父节点。

  • 克隆优化节点操作

克隆相似节点比直接创建新节点性能高

  • 直接量替换new Object
//优化前
var a1 = new Array(3)
a1[0] = 1
a1[1] = 2
a1[2] = 3
//优化后
var a = [1,2,3]
  • 减少判断层级
    判断不满足条件的直接处理或者return,减少不满足条件还浪费时间去判断嵌套的条件逻辑处理;
    多个else if 且对应具体的枚举值时,建议使用switch case。else if尽量只适用于区间条件判断。

  • 减少作用域链查找层级

  • 减少数据读取次数

将要频繁使用的值提前缓存

  • 使用字面量替换构造式
    字面量数据比构造式引用类型省时

  • 减少循环体中活动

  • 减少声明及语句数

不需要频繁使用的变量不提前声明,在使用时直接获取;
一次声明多个变量,减少语句数。

  • 多次调用时,使用惰性函数性能更优。惰性载入表示函数执行的分支只会在函数第一次调用的时候执行。一般是在第一次执行时将返回值存储在变量中,执行时直接获取。
  • 采用时间委托

JSBench

网址:jsbench .me

栈堆执行过程:

按照执行上下文的作用域链的原理,依次查找执行。当不再有外部引用时进行垃圾回收。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值